mirror of
https://github.com/postgres/postgres.git
synced 2025-04-25 21:42:33 +03:00
Make various variables const (read-only).
These changes should generally improve correctness/maintainability. A nice side benefit is that several kilobytes move from initialized data to text segment, allowing them to be shared across processes and probably reducing copy-on-write overhead while forking a new backend. Unfortunately this doesn't seem to help libpq in the same way (at least not when it's compiled with -fpic on x86_64), but we can hope the linker at least collects all nominally-const data together even if it's not actually part of the text segment. Also, make pg_encname_tbl[] static in encnames.c, since there seems no very good reason for any other code to use it; per a suggestion from Wim Lewis, who independently submitted a patch that was mostly a subset of this one. Oskari Saarenmaa, with some editorialization by me
This commit is contained in:
parent
7d7eee8bb7
commit
0d79c0a8cc
@ -101,7 +101,7 @@ typedef struct
|
|||||||
* class? */
|
* class? */
|
||||||
} ObjectPropertyType;
|
} ObjectPropertyType;
|
||||||
|
|
||||||
static ObjectPropertyType ObjectProperty[] =
|
static const ObjectPropertyType ObjectProperty[] =
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
CastRelationId,
|
CastRelationId,
|
||||||
@ -431,7 +431,7 @@ static ObjectAddress get_object_address_type(ObjectType objtype,
|
|||||||
List *objname, bool missing_ok);
|
List *objname, bool missing_ok);
|
||||||
static ObjectAddress get_object_address_opcf(ObjectType objtype, List *objname,
|
static ObjectAddress get_object_address_opcf(ObjectType objtype, List *objname,
|
||||||
List *objargs, bool missing_ok);
|
List *objargs, bool missing_ok);
|
||||||
static ObjectPropertyType *get_object_property_data(Oid class_id);
|
static const ObjectPropertyType *get_object_property_data(Oid class_id);
|
||||||
|
|
||||||
static void getRelationDescription(StringInfo buffer, Oid relid);
|
static void getRelationDescription(StringInfo buffer, Oid relid);
|
||||||
static void getOpFamilyDescription(StringInfo buffer, Oid opfid);
|
static void getOpFamilyDescription(StringInfo buffer, Oid opfid);
|
||||||
@ -1297,7 +1297,7 @@ get_object_namespace(const ObjectAddress *address)
|
|||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
bool isnull;
|
bool isnull;
|
||||||
Oid oid;
|
Oid oid;
|
||||||
ObjectPropertyType *property;
|
const ObjectPropertyType *property;
|
||||||
|
|
||||||
/* If not owned by a namespace, just return InvalidOid. */
|
/* If not owned by a namespace, just return InvalidOid. */
|
||||||
property = get_object_property_data(address->classId);
|
property = get_object_property_data(address->classId);
|
||||||
@ -1329,7 +1329,7 @@ get_object_namespace(const ObjectAddress *address)
|
|||||||
Oid
|
Oid
|
||||||
get_object_oid_index(Oid class_id)
|
get_object_oid_index(Oid class_id)
|
||||||
{
|
{
|
||||||
ObjectPropertyType *prop = get_object_property_data(class_id);
|
const ObjectPropertyType *prop = get_object_property_data(class_id);
|
||||||
|
|
||||||
return prop->oid_index_oid;
|
return prop->oid_index_oid;
|
||||||
}
|
}
|
||||||
@ -1337,7 +1337,7 @@ get_object_oid_index(Oid class_id)
|
|||||||
int
|
int
|
||||||
get_object_catcache_oid(Oid class_id)
|
get_object_catcache_oid(Oid class_id)
|
||||||
{
|
{
|
||||||
ObjectPropertyType *prop = get_object_property_data(class_id);
|
const ObjectPropertyType *prop = get_object_property_data(class_id);
|
||||||
|
|
||||||
return prop->oid_catcache_id;
|
return prop->oid_catcache_id;
|
||||||
}
|
}
|
||||||
@ -1345,7 +1345,7 @@ get_object_catcache_oid(Oid class_id)
|
|||||||
int
|
int
|
||||||
get_object_catcache_name(Oid class_id)
|
get_object_catcache_name(Oid class_id)
|
||||||
{
|
{
|
||||||
ObjectPropertyType *prop = get_object_property_data(class_id);
|
const ObjectPropertyType *prop = get_object_property_data(class_id);
|
||||||
|
|
||||||
return prop->name_catcache_id;
|
return prop->name_catcache_id;
|
||||||
}
|
}
|
||||||
@ -1353,7 +1353,7 @@ get_object_catcache_name(Oid class_id)
|
|||||||
AttrNumber
|
AttrNumber
|
||||||
get_object_attnum_name(Oid class_id)
|
get_object_attnum_name(Oid class_id)
|
||||||
{
|
{
|
||||||
ObjectPropertyType *prop = get_object_property_data(class_id);
|
const ObjectPropertyType *prop = get_object_property_data(class_id);
|
||||||
|
|
||||||
return prop->attnum_name;
|
return prop->attnum_name;
|
||||||
}
|
}
|
||||||
@ -1361,7 +1361,7 @@ get_object_attnum_name(Oid class_id)
|
|||||||
AttrNumber
|
AttrNumber
|
||||||
get_object_attnum_namespace(Oid class_id)
|
get_object_attnum_namespace(Oid class_id)
|
||||||
{
|
{
|
||||||
ObjectPropertyType *prop = get_object_property_data(class_id);
|
const ObjectPropertyType *prop = get_object_property_data(class_id);
|
||||||
|
|
||||||
return prop->attnum_namespace;
|
return prop->attnum_namespace;
|
||||||
}
|
}
|
||||||
@ -1369,7 +1369,7 @@ get_object_attnum_namespace(Oid class_id)
|
|||||||
AttrNumber
|
AttrNumber
|
||||||
get_object_attnum_owner(Oid class_id)
|
get_object_attnum_owner(Oid class_id)
|
||||||
{
|
{
|
||||||
ObjectPropertyType *prop = get_object_property_data(class_id);
|
const ObjectPropertyType *prop = get_object_property_data(class_id);
|
||||||
|
|
||||||
return prop->attnum_owner;
|
return prop->attnum_owner;
|
||||||
}
|
}
|
||||||
@ -1377,7 +1377,7 @@ get_object_attnum_owner(Oid class_id)
|
|||||||
AttrNumber
|
AttrNumber
|
||||||
get_object_attnum_acl(Oid class_id)
|
get_object_attnum_acl(Oid class_id)
|
||||||
{
|
{
|
||||||
ObjectPropertyType *prop = get_object_property_data(class_id);
|
const ObjectPropertyType *prop = get_object_property_data(class_id);
|
||||||
|
|
||||||
return prop->attnum_acl;
|
return prop->attnum_acl;
|
||||||
}
|
}
|
||||||
@ -1385,7 +1385,7 @@ get_object_attnum_acl(Oid class_id)
|
|||||||
AclObjectKind
|
AclObjectKind
|
||||||
get_object_aclkind(Oid class_id)
|
get_object_aclkind(Oid class_id)
|
||||||
{
|
{
|
||||||
ObjectPropertyType *prop = get_object_property_data(class_id);
|
const ObjectPropertyType *prop = get_object_property_data(class_id);
|
||||||
|
|
||||||
return prop->acl_kind;
|
return prop->acl_kind;
|
||||||
}
|
}
|
||||||
@ -1393,7 +1393,7 @@ get_object_aclkind(Oid class_id)
|
|||||||
bool
|
bool
|
||||||
get_object_namensp_unique(Oid class_id)
|
get_object_namensp_unique(Oid class_id)
|
||||||
{
|
{
|
||||||
ObjectPropertyType *prop = get_object_property_data(class_id);
|
const ObjectPropertyType *prop = get_object_property_data(class_id);
|
||||||
|
|
||||||
return prop->is_nsp_name_unique;
|
return prop->is_nsp_name_unique;
|
||||||
}
|
}
|
||||||
@ -1419,10 +1419,10 @@ is_objectclass_supported(Oid class_id)
|
|||||||
/*
|
/*
|
||||||
* Find ObjectProperty structure by class_id.
|
* Find ObjectProperty structure by class_id.
|
||||||
*/
|
*/
|
||||||
static ObjectPropertyType *
|
static const ObjectPropertyType *
|
||||||
get_object_property_data(Oid class_id)
|
get_object_property_data(Oid class_id)
|
||||||
{
|
{
|
||||||
static ObjectPropertyType *prop_last = NULL;
|
static const ObjectPropertyType *prop_last = NULL;
|
||||||
int index;
|
int index;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -46,7 +46,7 @@ CreateConversionCommand(CreateConversionStmt *stmt)
|
|||||||
const char *from_encoding_name = stmt->for_encoding_name;
|
const char *from_encoding_name = stmt->for_encoding_name;
|
||||||
const char *to_encoding_name = stmt->to_encoding_name;
|
const char *to_encoding_name = stmt->to_encoding_name;
|
||||||
List *func_name = stmt->func_name;
|
List *func_name = stmt->func_name;
|
||||||
static Oid funcargs[] = {INT4OID, INT4OID, CSTRINGOID, INTERNALOID, INT4OID};
|
static const Oid funcargs[] = {INT4OID, INT4OID, CSTRINGOID, INTERNALOID, INT4OID};
|
||||||
char result[1];
|
char result[1];
|
||||||
|
|
||||||
/* Convert list of names to a name and namespace */
|
/* Convert list of names to a name and namespace */
|
||||||
|
@ -716,10 +716,10 @@ static int /* not actually used, but convenient for RETV */
|
|||||||
lexescape(struct vars * v)
|
lexescape(struct vars * v)
|
||||||
{
|
{
|
||||||
chr c;
|
chr c;
|
||||||
static chr alert[] = {
|
static const chr alert[] = {
|
||||||
CHR('a'), CHR('l'), CHR('e'), CHR('r'), CHR('t')
|
CHR('a'), CHR('l'), CHR('e'), CHR('r'), CHR('t')
|
||||||
};
|
};
|
||||||
static chr esc[] = {
|
static const chr esc[] = {
|
||||||
CHR('E'), CHR('S'), CHR('C')
|
CHR('E'), CHR('S'), CHR('C')
|
||||||
};
|
};
|
||||||
const chr *save;
|
const chr *save;
|
||||||
|
@ -274,7 +274,7 @@ struct vars
|
|||||||
|
|
||||||
|
|
||||||
/* static function list */
|
/* static function list */
|
||||||
static struct fns functions = {
|
static const struct fns functions = {
|
||||||
rfree, /* regfree insides */
|
rfree, /* regfree insides */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -34,10 +34,10 @@
|
|||||||
#include "regex/regguts.h"
|
#include "regex/regguts.h"
|
||||||
|
|
||||||
/* unknown-error explanation */
|
/* unknown-error explanation */
|
||||||
static char unk[] = "*** unknown regex error code 0x%x ***";
|
static const char unk[] = "*** unknown regex error code 0x%x ***";
|
||||||
|
|
||||||
/* struct to map among codes, code names, and explanations */
|
/* struct to map among codes, code names, and explanations */
|
||||||
static struct rerr
|
static const struct rerr
|
||||||
{
|
{
|
||||||
int code;
|
int code;
|
||||||
const char *name;
|
const char *name;
|
||||||
@ -62,7 +62,7 @@ pg_regerror(int errcode, /* error code, or REG_ATOI or REG_ITOA */
|
|||||||
char *errbuf, /* result buffer (unless errbuf_size==0) */
|
char *errbuf, /* result buffer (unless errbuf_size==0) */
|
||||||
size_t errbuf_size) /* available space in errbuf, can be 0 */
|
size_t errbuf_size) /* available space in errbuf, can be 0 */
|
||||||
{
|
{
|
||||||
struct rerr *r;
|
const struct rerr *r;
|
||||||
const char *msg;
|
const char *msg;
|
||||||
char convbuf[sizeof(unk) + 50]; /* 50 = plenty for int */
|
char convbuf[sizeof(unk) + 50]; /* 50 = plenty for int */
|
||||||
size_t len;
|
size_t len;
|
||||||
|
@ -789,7 +789,7 @@ p_isspecial(TParser *prs)
|
|||||||
*/
|
*/
|
||||||
if (GetDatabaseEncoding() == PG_UTF8 && prs->usewide)
|
if (GetDatabaseEncoding() == PG_UTF8 && prs->usewide)
|
||||||
{
|
{
|
||||||
static pg_wchar strange_letter[] = {
|
static const pg_wchar strange_letter[] = {
|
||||||
/*
|
/*
|
||||||
* use binary search, so elements should be ordered
|
* use binary search, so elements should be ordered
|
||||||
*/
|
*/
|
||||||
@ -1023,7 +1023,7 @@ p_isspecial(TParser *prs)
|
|||||||
0xAA34, /* CHAM CONSONANT SIGN RA */
|
0xAA34, /* CHAM CONSONANT SIGN RA */
|
||||||
0xAA4D /* CHAM CONSONANT SIGN FINAL H */
|
0xAA4D /* CHAM CONSONANT SIGN FINAL H */
|
||||||
};
|
};
|
||||||
pg_wchar *StopLow = strange_letter,
|
const pg_wchar *StopLow = strange_letter,
|
||||||
*StopHigh = strange_letter + lengthof(strange_letter),
|
*StopHigh = strange_letter + lengthof(strange_letter),
|
||||||
*StopMiddle;
|
*StopMiddle;
|
||||||
pg_wchar c;
|
pg_wchar c;
|
||||||
|
@ -59,10 +59,10 @@ const int day_tab[2][13] =
|
|||||||
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0}
|
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
const char *const months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL};
|
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL};
|
||||||
|
|
||||||
char *days[] = {"Sunday", "Monday", "Tuesday", "Wednesday",
|
const char *const days[] = {"Sunday", "Monday", "Tuesday", "Wednesday",
|
||||||
"Thursday", "Friday", "Saturday", NULL};
|
"Thursday", "Friday", "Saturday", NULL};
|
||||||
|
|
||||||
|
|
||||||
@ -186,7 +186,7 @@ static const datetkn datetktbl[] = {
|
|||||||
|
|
||||||
static int szdatetktbl = sizeof datetktbl / sizeof datetktbl[0];
|
static int szdatetktbl = sizeof datetktbl / sizeof datetktbl[0];
|
||||||
|
|
||||||
static datetkn deltatktbl[] = {
|
static const datetkn deltatktbl[] = {
|
||||||
/* text, token, lexval */
|
/* text, token, lexval */
|
||||||
{"@", IGNORE_DTF, 0}, /* postgres relative prefix */
|
{"@", IGNORE_DTF, 0}, /* postgres relative prefix */
|
||||||
{DAGO, AGO, 0}, /* "ago" indicates negative time offset */
|
{DAGO, AGO, 0}, /* "ago" indicates negative time offset */
|
||||||
|
@ -121,13 +121,6 @@
|
|||||||
#define MAXDOUBLEWIDTH 500
|
#define MAXDOUBLEWIDTH 500
|
||||||
|
|
||||||
|
|
||||||
/* ----------
|
|
||||||
* External (defined in PgSQL datetime.c (timestamp utils))
|
|
||||||
* ----------
|
|
||||||
*/
|
|
||||||
extern char *months[], /* month abbreviation */
|
|
||||||
*days[]; /* full days */
|
|
||||||
|
|
||||||
/* ----------
|
/* ----------
|
||||||
* Format parser structs
|
* Format parser structs
|
||||||
* ----------
|
* ----------
|
||||||
@ -188,12 +181,12 @@ struct FormatNode
|
|||||||
* Full months
|
* Full months
|
||||||
* ----------
|
* ----------
|
||||||
*/
|
*/
|
||||||
static char *months_full[] = {
|
static const char *const months_full[] = {
|
||||||
"January", "February", "March", "April", "May", "June", "July",
|
"January", "February", "March", "April", "May", "June", "July",
|
||||||
"August", "September", "October", "November", "December", NULL
|
"August", "September", "October", "November", "December", NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
static char *days_short[] = {
|
static const char *const days_short[] = {
|
||||||
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", NULL
|
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -226,8 +219,8 @@ static char *days_short[] = {
|
|||||||
* matches for BC have an odd index. So the boolean value for BC is given by
|
* matches for BC have an odd index. So the boolean value for BC is given by
|
||||||
* taking the array index of the match, modulo 2.
|
* taking the array index of the match, modulo 2.
|
||||||
*/
|
*/
|
||||||
static char *adbc_strings[] = {ad_STR, bc_STR, AD_STR, BC_STR, NULL};
|
static const char *const adbc_strings[] = {ad_STR, bc_STR, AD_STR, BC_STR, NULL};
|
||||||
static char *adbc_strings_long[] = {a_d_STR, b_c_STR, A_D_STR, B_C_STR, NULL};
|
static const char *const adbc_strings_long[] = {a_d_STR, b_c_STR, A_D_STR, B_C_STR, NULL};
|
||||||
|
|
||||||
/* ----------
|
/* ----------
|
||||||
* AM / PM
|
* AM / PM
|
||||||
@ -253,8 +246,8 @@ static char *adbc_strings_long[] = {a_d_STR, b_c_STR, A_D_STR, B_C_STR, NULL};
|
|||||||
* matches for PM have an odd index. So the boolean value for PM is given by
|
* matches for PM have an odd index. So the boolean value for PM is given by
|
||||||
* taking the array index of the match, modulo 2.
|
* taking the array index of the match, modulo 2.
|
||||||
*/
|
*/
|
||||||
static char *ampm_strings[] = {am_STR, pm_STR, AM_STR, PM_STR, NULL};
|
static const char *const ampm_strings[] = {am_STR, pm_STR, AM_STR, PM_STR, NULL};
|
||||||
static char *ampm_strings_long[] = {a_m_STR, p_m_STR, A_M_STR, P_M_STR, NULL};
|
static const char *const ampm_strings_long[] = {a_m_STR, p_m_STR, A_M_STR, P_M_STR, NULL};
|
||||||
|
|
||||||
/* ----------
|
/* ----------
|
||||||
* Months in roman-numeral
|
* Months in roman-numeral
|
||||||
@ -262,26 +255,26 @@ static char *ampm_strings_long[] = {a_m_STR, p_m_STR, A_M_STR, P_M_STR, NULL};
|
|||||||
* 'VIII' must have higher precedence than 'V')
|
* 'VIII' must have higher precedence than 'V')
|
||||||
* ----------
|
* ----------
|
||||||
*/
|
*/
|
||||||
static char *rm_months_upper[] =
|
static const char *const rm_months_upper[] =
|
||||||
{"XII", "XI", "X", "IX", "VIII", "VII", "VI", "V", "IV", "III", "II", "I", NULL};
|
{"XII", "XI", "X", "IX", "VIII", "VII", "VI", "V", "IV", "III", "II", "I", NULL};
|
||||||
|
|
||||||
static char *rm_months_lower[] =
|
static const char *const rm_months_lower[] =
|
||||||
{"xii", "xi", "x", "ix", "viii", "vii", "vi", "v", "iv", "iii", "ii", "i", NULL};
|
{"xii", "xi", "x", "ix", "viii", "vii", "vi", "v", "iv", "iii", "ii", "i", NULL};
|
||||||
|
|
||||||
/* ----------
|
/* ----------
|
||||||
* Roman numbers
|
* Roman numbers
|
||||||
* ----------
|
* ----------
|
||||||
*/
|
*/
|
||||||
static char *rm1[] = {"I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", NULL};
|
static const char *const rm1[] = {"I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", NULL};
|
||||||
static char *rm10[] = {"X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC", NULL};
|
static const char *const rm10[] = {"X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC", NULL};
|
||||||
static char *rm100[] = {"C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM", NULL};
|
static const char *const rm100[] = {"C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM", NULL};
|
||||||
|
|
||||||
/* ----------
|
/* ----------
|
||||||
* Ordinal postfixes
|
* Ordinal postfixes
|
||||||
* ----------
|
* ----------
|
||||||
*/
|
*/
|
||||||
static char *numTH[] = {"ST", "ND", "RD", "TH", NULL};
|
static const char *const numTH[] = {"ST", "ND", "RD", "TH", NULL};
|
||||||
static char *numth[] = {"st", "nd", "rd", "th", NULL};
|
static const char *const numth[] = {"st", "nd", "rd", "th", NULL};
|
||||||
|
|
||||||
/* ----------
|
/* ----------
|
||||||
* Flags & Options:
|
* Flags & Options:
|
||||||
@ -525,7 +518,7 @@ do { \
|
|||||||
* Suffixes definition for DATE-TIME TO/FROM CHAR
|
* Suffixes definition for DATE-TIME TO/FROM CHAR
|
||||||
* ----------
|
* ----------
|
||||||
*/
|
*/
|
||||||
static KeySuffix DCH_suff[] = {
|
static const KeySuffix DCH_suff[] = {
|
||||||
{"FM", 2, DCH_S_FM, SUFFTYPE_PREFIX},
|
{"FM", 2, DCH_S_FM, SUFFTYPE_PREFIX},
|
||||||
{"fm", 2, DCH_S_FM, SUFFTYPE_PREFIX},
|
{"fm", 2, DCH_S_FM, SUFFTYPE_PREFIX},
|
||||||
{"TM", 2, DCH_S_TM, SUFFTYPE_PREFIX},
|
{"TM", 2, DCH_S_TM, SUFFTYPE_PREFIX},
|
||||||
@ -950,10 +943,10 @@ typedef struct NUMProc
|
|||||||
*/
|
*/
|
||||||
static const KeyWord *index_seq_search(char *str, const KeyWord *kw,
|
static const KeyWord *index_seq_search(char *str, const KeyWord *kw,
|
||||||
const int *index);
|
const int *index);
|
||||||
static KeySuffix *suff_search(char *str, KeySuffix *suf, int type);
|
static const KeySuffix *suff_search(char *str, const KeySuffix *suf, int type);
|
||||||
static void NUMDesc_prepare(NUMDesc *num, FormatNode *n);
|
static void NUMDesc_prepare(NUMDesc *num, FormatNode *n);
|
||||||
static void parse_format(FormatNode *node, char *str, const KeyWord *kw,
|
static void parse_format(FormatNode *node, char *str, const KeyWord *kw,
|
||||||
KeySuffix *suf, const int *index, int ver, NUMDesc *Num);
|
const KeySuffix *suf, const int *index, int ver, NUMDesc *Num);
|
||||||
|
|
||||||
static void DCH_to_char(FormatNode *node, bool is_interval,
|
static void DCH_to_char(FormatNode *node, bool is_interval,
|
||||||
TmToChar *in, char *out, Oid collid);
|
TmToChar *in, char *out, Oid collid);
|
||||||
@ -964,7 +957,7 @@ static void dump_index(const KeyWord *k, const int *index);
|
|||||||
static void dump_node(FormatNode *node, int max);
|
static void dump_node(FormatNode *node, int max);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static char *get_th(char *num, int type);
|
static const char *get_th(char *num, int type);
|
||||||
static char *str_numth(char *dest, char *num, int type);
|
static char *str_numth(char *dest, char *num, int type);
|
||||||
static int adjust_partial_year_to_2020(int year);
|
static int adjust_partial_year_to_2020(int year);
|
||||||
static int strspace_len(char *str);
|
static int strspace_len(char *str);
|
||||||
@ -973,8 +966,8 @@ static void from_char_set_mode(TmFromChar *tmfc, const FromCharDateMode mode);
|
|||||||
static void from_char_set_int(int *dest, const int value, const FormatNode *node);
|
static void from_char_set_int(int *dest, const int value, const FormatNode *node);
|
||||||
static int from_char_parse_int_len(int *dest, char **src, const int len, FormatNode *node);
|
static int from_char_parse_int_len(int *dest, char **src, const int len, FormatNode *node);
|
||||||
static int from_char_parse_int(int *dest, char **src, FormatNode *node);
|
static int from_char_parse_int(int *dest, char **src, FormatNode *node);
|
||||||
static int seq_search(char *name, char **array, int type, int max, int *len);
|
static int seq_search(char *name, const char *const * array, int type, int max, int *len);
|
||||||
static int from_char_seq_search(int *dest, char **src, char **array, int type, int max, FormatNode *node);
|
static int from_char_seq_search(int *dest, char **src, const char *const * array, int type, int max, FormatNode *node);
|
||||||
static void do_to_timestamp(text *date_txt, text *fmt,
|
static void do_to_timestamp(text *date_txt, text *fmt,
|
||||||
struct pg_tm * tm, fsec_t *fsec);
|
struct pg_tm * tm, fsec_t *fsec);
|
||||||
static char *fill_str(char *str, int c, int max);
|
static char *fill_str(char *str, int c, int max);
|
||||||
@ -1024,10 +1017,10 @@ index_seq_search(char *str, const KeyWord *kw, const int *index)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static KeySuffix *
|
static const KeySuffix *
|
||||||
suff_search(char *str, KeySuffix *suf, int type)
|
suff_search(char *str, const KeySuffix *suf, int type)
|
||||||
{
|
{
|
||||||
KeySuffix *s;
|
const KeySuffix *s;
|
||||||
|
|
||||||
for (s = suf; s->name != NULL; s++)
|
for (s = suf; s->name != NULL; s++)
|
||||||
{
|
{
|
||||||
@ -1237,9 +1230,9 @@ NUMDesc_prepare(NUMDesc *num, FormatNode *n)
|
|||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
parse_format(FormatNode *node, char *str, const KeyWord *kw,
|
parse_format(FormatNode *node, char *str, const KeyWord *kw,
|
||||||
KeySuffix *suf, const int *index, int ver, NUMDesc *Num)
|
const KeySuffix *suf, const int *index, int ver, NUMDesc *Num)
|
||||||
{
|
{
|
||||||
KeySuffix *s;
|
const KeySuffix *s;
|
||||||
FormatNode *n;
|
FormatNode *n;
|
||||||
int node_set = 0,
|
int node_set = 0,
|
||||||
suffix,
|
suffix,
|
||||||
@ -1401,7 +1394,7 @@ dump_node(FormatNode *node, int max)
|
|||||||
* type --> 0 upper, 1 lower
|
* type --> 0 upper, 1 lower
|
||||||
* ----------
|
* ----------
|
||||||
*/
|
*/
|
||||||
static char *
|
static const char *
|
||||||
get_th(char *num, int type)
|
get_th(char *num, int type)
|
||||||
{
|
{
|
||||||
int len = strlen(num),
|
int len = strlen(num),
|
||||||
@ -2268,11 +2261,11 @@ from_char_parse_int(int *dest, char **src, FormatNode *node)
|
|||||||
* ----------
|
* ----------
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
seq_search(char *name, char **array, int type, int max, int *len)
|
seq_search(char *name, const char *const * array, int type, int max, int *len)
|
||||||
{
|
{
|
||||||
char *p,
|
const char *p;
|
||||||
*n,
|
const char *const * a;
|
||||||
**a;
|
char *n;
|
||||||
int last,
|
int last,
|
||||||
i;
|
i;
|
||||||
|
|
||||||
@ -2346,7 +2339,7 @@ seq_search(char *name, char **array, int type, int max, int *len)
|
|||||||
* If the string doesn't match, throw an error.
|
* If the string doesn't match, throw an error.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
from_char_seq_search(int *dest, char **src, char **array, int type, int max,
|
from_char_seq_search(int *dest, char **src, const char *const * array, int type, int max,
|
||||||
FormatNode *node)
|
FormatNode *node)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
|
|
||||||
|
|
||||||
static float weights[] = {0.1f, 0.2f, 0.4f, 1.0f};
|
static const float weights[] = {0.1f, 0.2f, 0.4f, 1.0f};
|
||||||
|
|
||||||
#define wpos(wep) ( w[ WEP_GETWEIGHT(wep) ] )
|
#define wpos(wep) ( w[ WEP_GETWEIGHT(wep) ] )
|
||||||
|
|
||||||
@ -33,8 +33,8 @@ static float weights[] = {0.1f, 0.2f, 0.4f, 1.0f};
|
|||||||
#define RANK_NORM_RDIVRPLUS1 0x20
|
#define RANK_NORM_RDIVRPLUS1 0x20
|
||||||
#define DEF_NORM_METHOD RANK_NO_NORM
|
#define DEF_NORM_METHOD RANK_NO_NORM
|
||||||
|
|
||||||
static float calc_rank_or(float *w, TSVector t, TSQuery q);
|
static float calc_rank_or(const float *w, TSVector t, TSQuery q);
|
||||||
static float calc_rank_and(float *w, TSVector t, TSQuery q);
|
static float calc_rank_and(const float *w, TSVector t, TSQuery q);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns a weight of a word collocation
|
* Returns a weight of a word collocation
|
||||||
@ -202,7 +202,7 @@ static WordEntryPosVector POSNULL = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static float
|
static float
|
||||||
calc_rank_and(float *w, TSVector t, TSQuery q)
|
calc_rank_and(const float *w, TSVector t, TSQuery q)
|
||||||
{
|
{
|
||||||
WordEntryPosVector **pos;
|
WordEntryPosVector **pos;
|
||||||
int i,
|
int i,
|
||||||
@ -278,7 +278,7 @@ calc_rank_and(float *w, TSVector t, TSQuery q)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static float
|
static float
|
||||||
calc_rank_or(float *w, TSVector t, TSQuery q)
|
calc_rank_or(const float *w, TSVector t, TSQuery q)
|
||||||
{
|
{
|
||||||
WordEntry *entry,
|
WordEntry *entry,
|
||||||
*firstentry;
|
*firstentry;
|
||||||
@ -347,7 +347,7 @@ calc_rank_or(float *w, TSVector t, TSQuery q)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static float
|
static float
|
||||||
calc_rank(float *w, TSVector t, TSQuery q, int32 method)
|
calc_rank(const float *w, TSVector t, TSQuery q, int32 method)
|
||||||
{
|
{
|
||||||
QueryItem *item = GETQUERY(q);
|
QueryItem *item = GETQUERY(q);
|
||||||
float res = 0.0;
|
float res = 0.0;
|
||||||
@ -387,7 +387,7 @@ calc_rank(float *w, TSVector t, TSQuery q, int32 method)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static float *
|
static const float *
|
||||||
getWeights(ArrayType *win)
|
getWeights(ArrayType *win)
|
||||||
{
|
{
|
||||||
static float ws[lengthof(weights)];
|
static float ws[lengthof(weights)];
|
||||||
@ -723,7 +723,7 @@ get_docrep(TSVector txt, QueryRepresentation *qr, int *doclen)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static float4
|
static float4
|
||||||
calc_rank_cd(float4 *arrdata, TSVector txt, TSQuery query, int method)
|
calc_rank_cd(const float4 *arrdata, TSVector txt, TSQuery query, int method)
|
||||||
{
|
{
|
||||||
DocRepresentation *doc;
|
DocRepresentation *doc;
|
||||||
int len,
|
int len,
|
||||||
|
@ -29,7 +29,13 @@
|
|||||||
* Karel Zak, Aug 2001
|
* Karel Zak, Aug 2001
|
||||||
* ----------
|
* ----------
|
||||||
*/
|
*/
|
||||||
pg_encname pg_encname_tbl[] =
|
typedef struct pg_encname
|
||||||
|
{
|
||||||
|
const char *name;
|
||||||
|
pg_enc encoding;
|
||||||
|
} pg_encname;
|
||||||
|
|
||||||
|
static const pg_encname pg_encname_tbl[] =
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
"abc", PG_WIN1258
|
"abc", PG_WIN1258
|
||||||
@ -285,15 +291,9 @@ pg_encname pg_encname_tbl[] =
|
|||||||
}, /* alias for UHC */
|
}, /* alias for UHC */
|
||||||
{
|
{
|
||||||
"windows950", PG_BIG5
|
"windows950", PG_BIG5
|
||||||
}, /* alias for BIG5 */
|
} /* alias for BIG5 */
|
||||||
{
|
|
||||||
NULL, 0
|
|
||||||
} /* last */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned int pg_encname_tbl_sz = \
|
|
||||||
sizeof(pg_encname_tbl) / sizeof(pg_encname_tbl[0]) - 1;
|
|
||||||
|
|
||||||
/* ----------
|
/* ----------
|
||||||
* These are "official" encoding names.
|
* These are "official" encoding names.
|
||||||
* XXX must be sorted by the same order as enum pg_enc (in mb/pg_wchar.h)
|
* XXX must be sorted by the same order as enum pg_enc (in mb/pg_wchar.h)
|
||||||
@ -304,7 +304,7 @@ sizeof(pg_encname_tbl) / sizeof(pg_encname_tbl[0]) - 1;
|
|||||||
#else
|
#else
|
||||||
#define DEF_ENC2NAME(name, codepage) { #name, PG_##name, codepage }
|
#define DEF_ENC2NAME(name, codepage) { #name, PG_##name, codepage }
|
||||||
#endif
|
#endif
|
||||||
pg_enc2name pg_enc2name_tbl[] =
|
const pg_enc2name pg_enc2name_tbl[] =
|
||||||
{
|
{
|
||||||
DEF_ENC2NAME(SQL_ASCII, 0),
|
DEF_ENC2NAME(SQL_ASCII, 0),
|
||||||
DEF_ENC2NAME(EUC_JP, 20932),
|
DEF_ENC2NAME(EUC_JP, 20932),
|
||||||
@ -356,7 +356,7 @@ pg_enc2name pg_enc2name_tbl[] =
|
|||||||
* This covers all encodings except MULE_INTERNAL, which is alien to gettext.
|
* This covers all encodings except MULE_INTERNAL, which is alien to gettext.
|
||||||
* ----------
|
* ----------
|
||||||
*/
|
*/
|
||||||
pg_enc2gettext pg_enc2gettext_tbl[] =
|
const pg_enc2gettext pg_enc2gettext_tbl[] =
|
||||||
{
|
{
|
||||||
{PG_SQL_ASCII, "US-ASCII"},
|
{PG_SQL_ASCII, "US-ASCII"},
|
||||||
{PG_UTF8, "UTF-8"},
|
{PG_UTF8, "UTF-8"},
|
||||||
@ -467,13 +467,15 @@ clean_encoding_name(const char *key, char *newkey)
|
|||||||
|
|
||||||
/* ----------
|
/* ----------
|
||||||
* Search encoding by encoding name
|
* Search encoding by encoding name
|
||||||
|
*
|
||||||
|
* Returns encoding ID, or -1 for error
|
||||||
* ----------
|
* ----------
|
||||||
*/
|
*/
|
||||||
pg_encname *
|
int
|
||||||
pg_char_to_encname_struct(const char *name)
|
pg_char_to_encoding(const char *name)
|
||||||
{
|
{
|
||||||
unsigned int nel = pg_encname_tbl_sz;
|
unsigned int nel = lengthof(pg_encname_tbl);
|
||||||
pg_encname *base = pg_encname_tbl,
|
const pg_encname *base = pg_encname_tbl,
|
||||||
*last = base + nel - 1,
|
*last = base + nel - 1,
|
||||||
*position;
|
*position;
|
||||||
int result;
|
int result;
|
||||||
@ -481,13 +483,13 @@ pg_char_to_encname_struct(const char *name)
|
|||||||
*key;
|
*key;
|
||||||
|
|
||||||
if (name == NULL || *name == '\0')
|
if (name == NULL || *name == '\0')
|
||||||
return NULL;
|
return -1;
|
||||||
|
|
||||||
if (strlen(name) >= NAMEDATALEN)
|
if (strlen(name) >= NAMEDATALEN)
|
||||||
{
|
{
|
||||||
#ifdef FRONTEND
|
#ifdef FRONTEND
|
||||||
fprintf(stderr, "encoding name too long\n");
|
fprintf(stderr, "encoding name too long\n");
|
||||||
return NULL;
|
return -1;
|
||||||
#else
|
#else
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_NAME_TOO_LONG),
|
(errcode(ERRCODE_NAME_TOO_LONG),
|
||||||
@ -505,29 +507,14 @@ pg_char_to_encname_struct(const char *name)
|
|||||||
{
|
{
|
||||||
result = strcmp(key, position->name);
|
result = strcmp(key, position->name);
|
||||||
if (result == 0)
|
if (result == 0)
|
||||||
return position;
|
return position->encoding;
|
||||||
}
|
}
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
last = position - 1;
|
last = position - 1;
|
||||||
else
|
else
|
||||||
base = position + 1;
|
base = position + 1;
|
||||||
}
|
}
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns encoding or -1 for error
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
pg_char_to_encoding(const char *name)
|
|
||||||
{
|
|
||||||
pg_encname *p;
|
|
||||||
|
|
||||||
if (!name)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
p = pg_char_to_encname_struct(name);
|
|
||||||
return p ? p->encoding : -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef FRONTEND
|
#ifndef FRONTEND
|
||||||
@ -545,7 +532,7 @@ pg_encoding_to_char(int encoding)
|
|||||||
{
|
{
|
||||||
if (PG_VALID_ENCODING(encoding))
|
if (PG_VALID_ENCODING(encoding))
|
||||||
{
|
{
|
||||||
pg_enc2name *p = &pg_enc2name_tbl[encoding];
|
const pg_enc2name *p = &pg_enc2name_tbl[encoding];
|
||||||
|
|
||||||
Assert(encoding == p->encoding);
|
Assert(encoding == p->encoding);
|
||||||
return p->name;
|
return p->name;
|
||||||
|
@ -55,9 +55,9 @@ static FmgrInfo *ToClientConvProc = NULL;
|
|||||||
/*
|
/*
|
||||||
* These variables track the currently-selected encodings.
|
* These variables track the currently-selected encodings.
|
||||||
*/
|
*/
|
||||||
static pg_enc2name *ClientEncoding = &pg_enc2name_tbl[PG_SQL_ASCII];
|
static const pg_enc2name *ClientEncoding = &pg_enc2name_tbl[PG_SQL_ASCII];
|
||||||
static pg_enc2name *DatabaseEncoding = &pg_enc2name_tbl[PG_SQL_ASCII];
|
static const pg_enc2name *DatabaseEncoding = &pg_enc2name_tbl[PG_SQL_ASCII];
|
||||||
static pg_enc2name *MessageEncoding = &pg_enc2name_tbl[PG_SQL_ASCII];
|
static const pg_enc2name *MessageEncoding = &pg_enc2name_tbl[PG_SQL_ASCII];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* During backend startup we can't set client encoding because we (a)
|
* During backend startup we can't set client encoding because we (a)
|
||||||
|
@ -1720,7 +1720,7 @@ pg_eucjp_increment(unsigned char *charptr, int length)
|
|||||||
* XXX must be sorted by the same order as enum pg_enc (in mb/pg_wchar.h)
|
* XXX must be sorted by the same order as enum pg_enc (in mb/pg_wchar.h)
|
||||||
*-------------------------------------------------------------------
|
*-------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
pg_wchar_tbl pg_wchar_table[] = {
|
const pg_wchar_tbl pg_wchar_table[] = {
|
||||||
{pg_ascii2wchar_with_len, pg_wchar2single_with_len, pg_ascii_mblen, pg_ascii_dsplen, pg_ascii_verifier, 1}, /* PG_SQL_ASCII */
|
{pg_ascii2wchar_with_len, pg_wchar2single_with_len, pg_ascii_mblen, pg_ascii_dsplen, pg_ascii_verifier, 1}, /* PG_SQL_ASCII */
|
||||||
{pg_eucjp2wchar_with_len, pg_wchar2euc_with_len, pg_eucjp_mblen, pg_eucjp_dsplen, pg_eucjp_verifier, 3}, /* PG_EUC_JP */
|
{pg_eucjp2wchar_with_len, pg_wchar2euc_with_len, pg_eucjp_mblen, pg_eucjp_dsplen, pg_eucjp_verifier, 3}, /* PG_EUC_JP */
|
||||||
{pg_euccn2wchar_with_len, pg_wchar2euc_with_len, pg_euccn_mblen, pg_euccn_dsplen, pg_euccn_verifier, 2}, /* PG_EUC_CN */
|
{pg_euccn2wchar_with_len, pg_wchar2euc_with_len, pg_euccn_mblen, pg_euccn_dsplen, pg_euccn_verifier, 2}, /* PG_EUC_CN */
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
* documentation for pg_relation_size(). Also keep FORKNAMECHARS above
|
* documentation for pg_relation_size(). Also keep FORKNAMECHARS above
|
||||||
* up-to-date.
|
* up-to-date.
|
||||||
*/
|
*/
|
||||||
const char *forkNames[] = {
|
const char *const forkNames[] = {
|
||||||
"main", /* MAIN_FORKNUM */
|
"main", /* MAIN_FORKNUM */
|
||||||
"fsm", /* FSM_FORKNUM */
|
"fsm", /* FSM_FORKNUM */
|
||||||
"vm", /* VISIBILITYMAP_FORKNUM */
|
"vm", /* VISIBILITYMAP_FORKNUM */
|
||||||
|
@ -25,7 +25,8 @@
|
|||||||
#define TABLESPACE_VERSION_DIRECTORY "PG_" PG_MAJORVERSION "_" \
|
#define TABLESPACE_VERSION_DIRECTORY "PG_" PG_MAJORVERSION "_" \
|
||||||
CppAsString2(CATALOG_VERSION_NO)
|
CppAsString2(CATALOG_VERSION_NO)
|
||||||
|
|
||||||
extern const char *forkNames[];
|
extern const char *const forkNames[];
|
||||||
|
|
||||||
extern int forkname_chars(const char *str, ForkNumber *fork);
|
extern int forkname_chars(const char *str, ForkNumber *fork);
|
||||||
extern char *relpathbackend(RelFileNode rnode, BackendId backend,
|
extern char *relpathbackend(RelFileNode rnode, BackendId backend,
|
||||||
ForkNumber forknum);
|
ForkNumber forknum);
|
||||||
|
@ -303,33 +303,23 @@ typedef enum pg_enc
|
|||||||
#define PG_VALID_FE_ENCODING(_enc) PG_VALID_ENCODING(_enc)
|
#define PG_VALID_FE_ENCODING(_enc) PG_VALID_ENCODING(_enc)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Encoding names with all aliases
|
* Table for mapping an encoding number to official encoding name and
|
||||||
*/
|
* possibly other subsidiary data. Be careful to check encoding number
|
||||||
typedef struct pg_encname
|
* before accessing a table entry!
|
||||||
{
|
|
||||||
char *name;
|
|
||||||
pg_enc encoding;
|
|
||||||
} pg_encname;
|
|
||||||
|
|
||||||
extern pg_encname pg_encname_tbl[];
|
|
||||||
extern unsigned int pg_encname_tbl_sz;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Careful:
|
|
||||||
*
|
*
|
||||||
* if (PG_VALID_ENCODING(encoding))
|
* if (PG_VALID_ENCODING(encoding))
|
||||||
* pg_enc2name_tbl[ encoding ];
|
* pg_enc2name_tbl[ encoding ];
|
||||||
*/
|
*/
|
||||||
typedef struct pg_enc2name
|
typedef struct pg_enc2name
|
||||||
{
|
{
|
||||||
char *name;
|
const char *name;
|
||||||
pg_enc encoding;
|
pg_enc encoding;
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
unsigned codepage; /* codepage for WIN32 */
|
unsigned codepage; /* codepage for WIN32 */
|
||||||
#endif
|
#endif
|
||||||
} pg_enc2name;
|
} pg_enc2name;
|
||||||
|
|
||||||
extern pg_enc2name pg_enc2name_tbl[];
|
extern const pg_enc2name pg_enc2name_tbl[];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Encoding names for gettext
|
* Encoding names for gettext
|
||||||
@ -340,7 +330,7 @@ typedef struct pg_enc2gettext
|
|||||||
const char *name;
|
const char *name;
|
||||||
} pg_enc2gettext;
|
} pg_enc2gettext;
|
||||||
|
|
||||||
extern pg_enc2gettext pg_enc2gettext_tbl[];
|
extern const pg_enc2gettext pg_enc2gettext_tbl[];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* pg_wchar stuff
|
* pg_wchar stuff
|
||||||
@ -373,7 +363,7 @@ typedef struct
|
|||||||
int maxmblen; /* max bytes for a char in this encoding */
|
int maxmblen; /* max bytes for a char in this encoding */
|
||||||
} pg_wchar_tbl;
|
} pg_wchar_tbl;
|
||||||
|
|
||||||
extern pg_wchar_tbl pg_wchar_table[];
|
extern const pg_wchar_tbl pg_wchar_table[];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* UTF-8 to local code conversion map
|
* UTF-8 to local code conversion map
|
||||||
@ -441,8 +431,6 @@ extern int pg_valid_server_encoding_id(int encoding);
|
|||||||
* Remaining functions are not considered part of libpq's API, though many
|
* Remaining functions are not considered part of libpq's API, though many
|
||||||
* of them do exist inside libpq.
|
* of them do exist inside libpq.
|
||||||
*/
|
*/
|
||||||
extern pg_encname *pg_char_to_encname_struct(const char *name);
|
|
||||||
|
|
||||||
extern int pg_mb2wchar(const char *from, pg_wchar *to);
|
extern int pg_mb2wchar(const char *from, pg_wchar *to);
|
||||||
extern int pg_mb2wchar_with_len(const char *from, pg_wchar *to, int len);
|
extern int pg_mb2wchar_with_len(const char *from, pg_wchar *to, int len);
|
||||||
extern int pg_encoding_mb2wchar_with_len(int encoding,
|
extern int pg_encoding_mb2wchar_with_len(int encoding,
|
||||||
|
@ -247,6 +247,8 @@ do { \
|
|||||||
* Include check for leap year.
|
* Include check for leap year.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
extern const char *const months[]; /* months (3-char abbreviations) */
|
||||||
|
extern const char *const days[]; /* days (full names) */
|
||||||
extern const int day_tab[2][13];
|
extern const int day_tab[2][13];
|
||||||
|
|
||||||
#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
|
#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user