⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 formatting.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 5 页
字号:
	DCH_hh24,	DCH_hh12,	DCH_hh,	DCH_iw,	DCH_iyyy,	DCH_iyy,	DCH_iy,	DCH_i,	DCH_j,	DCH_mi,	DCH_mm,	DCH_month,	DCH_mon,	DCH_ms,	DCH_p_m,	DCH_pm,	DCH_q,	DCH_rm,	DCH_ssss,	DCH_ss,	DCH_tz,	DCH_us,	DCH_ww,	DCH_w,	DCH_y_yyy,	DCH_yyyy,	DCH_yyy,	DCH_yy,	DCH_y,	/* last */	_DCH_last_} DCH_poz;typedef enum{	NUM_COMMA,	NUM_DEC,	NUM_0,	NUM_9,	NUM_B,	NUM_C,	NUM_D,	NUM_E,	NUM_FM,	NUM_G,	NUM_L,	NUM_MI,	NUM_PL,	NUM_PR,	NUM_RN,	NUM_SG,	NUM_SP,	NUM_S,	NUM_TH,	NUM_V,	NUM_b,	NUM_c,	NUM_d,	NUM_e,	NUM_fm,	NUM_g,	NUM_l,	NUM_mi,	NUM_pl,	NUM_pr,	NUM_rn,	NUM_sg,	NUM_sp,	NUM_s,	NUM_th,	NUM_v,	/* last */	_NUM_last_} NUM_poz;/* ---------- * KeyWords for DATE-TIME version * ---------- */static const KeyWord DCH_keywords[] = {/*	keyword, len, func, type, isitdigit			 is in Index */	{"A.D.", 4, dch_date, DCH_A_D, FALSE},		/* A */	{"A.M.", 4, dch_time, DCH_A_M, FALSE},	{"AD", 2, dch_date, DCH_AD, FALSE},	{"AM", 2, dch_time, DCH_AM, FALSE},	{"B.C.", 4, dch_date, DCH_B_C, FALSE},		/* B */	{"BC", 2, dch_date, DCH_BC, FALSE},	{"CC", 2, dch_date, DCH_CC, TRUE},	/* C */	{"DAY", 3, dch_date, DCH_DAY, FALSE},		/* D */	{"DDD", 3, dch_date, DCH_DDD, TRUE},	{"DD", 2, dch_date, DCH_DD, TRUE},	{"DY", 2, dch_date, DCH_DY, FALSE},	{"Day", 3, dch_date, DCH_Day, FALSE},	{"Dy", 2, dch_date, DCH_Dy, FALSE},	{"D", 1, dch_date, DCH_D, TRUE},	{"FX", 2, dch_global, DCH_FX, FALSE},		/* F */	{"HH24", 4, dch_time, DCH_HH24, TRUE},		/* H */	{"HH12", 4, dch_time, DCH_HH12, TRUE},	{"HH", 2, dch_time, DCH_HH, TRUE},	{"IW", 2, dch_date, DCH_IW, TRUE},	/* I */	{"IYYY", 4, dch_date, DCH_IYYY, TRUE},	{"IYY", 3, dch_date, DCH_IYY, TRUE},	{"IY", 2, dch_date, DCH_IY, TRUE},	{"I", 1, dch_date, DCH_I, TRUE},	{"J", 1, dch_date, DCH_J, TRUE},	/* J */	{"MI", 2, dch_time, DCH_MI, TRUE},	{"MM", 2, dch_date, DCH_MM, TRUE},	{"MONTH", 5, dch_date, DCH_MONTH, FALSE},	{"MON", 3, dch_date, DCH_MON, FALSE},	{"MS", 2, dch_time, DCH_MS, TRUE},	{"Month", 5, dch_date, DCH_Month, FALSE},	{"Mon", 3, dch_date, DCH_Mon, FALSE},	{"P.M.", 4, dch_time, DCH_P_M, FALSE},		/* P */	{"PM", 2, dch_time, DCH_PM, FALSE},	{"Q", 1, dch_date, DCH_Q, TRUE},	/* Q */	{"RM", 2, dch_date, DCH_RM, FALSE}, /* R */	{"SSSS", 4, dch_time, DCH_SSSS, TRUE},		/* S */	{"SS", 2, dch_time, DCH_SS, TRUE},	{"TZ", 2, dch_time, DCH_TZ, FALSE}, /* T */	{"US", 2, dch_time, DCH_US, TRUE},	/* U */	{"WW", 2, dch_date, DCH_WW, TRUE},	/* W */	{"W", 1, dch_date, DCH_W, TRUE},	{"Y,YYY", 5, dch_date, DCH_Y_YYY, TRUE},	/* Y */	{"YYYY", 4, dch_date, DCH_YYYY, TRUE},	{"YYY", 3, dch_date, DCH_YYY, TRUE},	{"YY", 2, dch_date, DCH_YY, TRUE},	{"Y", 1, dch_date, DCH_Y, TRUE},	{"a.d.", 4, dch_date, DCH_a_d, FALSE},		/* a */	{"a.m.", 4, dch_time, DCH_a_m, FALSE},	{"ad", 2, dch_date, DCH_ad, FALSE},	{"am", 2, dch_time, DCH_am, FALSE},	{"b.c.", 4, dch_date, DCH_b_c, FALSE},		/* b */	{"bc", 2, dch_date, DCH_bc, FALSE},	{"cc", 2, dch_date, DCH_CC, TRUE},	/* c */	{"day", 3, dch_date, DCH_day, FALSE},		/* d */	{"ddd", 3, dch_date, DCH_DDD, TRUE},	{"dd", 2, dch_date, DCH_DD, TRUE},	{"dy", 2, dch_date, DCH_dy, FALSE},	{"d", 1, dch_date, DCH_D, TRUE},	{"fx", 2, dch_global, DCH_FX, FALSE},		/* f */	{"hh24", 4, dch_time, DCH_HH24, TRUE},		/* h */	{"hh12", 4, dch_time, DCH_HH12, TRUE},	{"hh", 2, dch_time, DCH_HH, TRUE},	{"iw", 2, dch_date, DCH_IW, TRUE},	/* i */	{"iyyy", 4, dch_date, DCH_IYYY, TRUE},	{"iyy", 3, dch_date, DCH_IYY, TRUE},	{"iy", 2, dch_date, DCH_IY, TRUE},	{"i", 1, dch_date, DCH_I, TRUE},	{"j", 1, dch_time, DCH_J, TRUE},	/* j */	{"mi", 2, dch_time, DCH_MI, TRUE},	/* m */	{"mm", 2, dch_date, DCH_MM, TRUE},	{"month", 5, dch_date, DCH_month, FALSE},	{"mon", 3, dch_date, DCH_mon, FALSE},	{"ms", 2, dch_time, DCH_MS, TRUE},	{"p.m.", 4, dch_time, DCH_p_m, FALSE},		/* p */	{"pm", 2, dch_time, DCH_pm, FALSE},	{"q", 1, dch_date, DCH_Q, TRUE},	/* q */	{"rm", 2, dch_date, DCH_rm, FALSE}, /* r */	{"ssss", 4, dch_time, DCH_SSSS, TRUE},		/* s */	{"ss", 2, dch_time, DCH_SS, TRUE},	{"tz", 2, dch_time, DCH_tz, FALSE}, /* t */	{"us", 2, dch_time, DCH_US, TRUE},	/* u */	{"ww", 2, dch_date, DCH_WW, TRUE},	/* w */	{"w", 1, dch_date, DCH_W, TRUE},	{"y,yyy", 5, dch_date, DCH_Y_YYY, TRUE},	/* y */	{"yyyy", 4, dch_date, DCH_YYYY, TRUE},	{"yyy", 3, dch_date, DCH_YYY, TRUE},	{"yy", 2, dch_date, DCH_YY, TRUE},	{"y", 1, dch_date, DCH_Y, TRUE},/* last */{NULL, 0, NULL, 0}};/* ---------- * KeyWords for NUMBER version (now, isitdigit info is not needful here..) * ---------- */static const KeyWord NUM_keywords[] = {/*	keyword,	len, func.	type			   is in Index */	{",", 1, NULL, NUM_COMMA},	/* , */	{".", 1, NULL, NUM_DEC},	/* . */	{"0", 1, NULL, NUM_0},		/* 0 */	{"9", 1, NULL, NUM_9},		/* 9 */	{"B", 1, NULL, NUM_B},		/* B */	{"C", 1, NULL, NUM_C},		/* C */	{"D", 1, NULL, NUM_D},		/* D */	{"E", 1, NULL, NUM_E},		/* E */	{"FM", 2, NULL, NUM_FM},	/* F */	{"G", 1, NULL, NUM_G},		/* G */	{"L", 1, NULL, NUM_L},		/* L */	{"MI", 2, NULL, NUM_MI},	/* M */	{"PL", 2, NULL, NUM_PL},	/* P */	{"PR", 2, NULL, NUM_PR},	{"RN", 2, NULL, NUM_RN},	/* R */	{"SG", 2, NULL, NUM_SG},	/* S */	{"SP", 2, NULL, NUM_SP},	{"S", 1, NULL, NUM_S},	{"TH", 2, NULL, NUM_TH},	/* T */	{"V", 1, NULL, NUM_V},		/* V */	{"b", 1, NULL, NUM_B},		/* b */	{"c", 1, NULL, NUM_C},		/* c */	{"d", 1, NULL, NUM_D},		/* d */	{"e", 1, NULL, NUM_E},		/* e */	{"fm", 2, NULL, NUM_FM},	/* f */	{"g", 1, NULL, NUM_G},		/* g */	{"l", 1, NULL, NUM_L},		/* l */	{"mi", 2, NULL, NUM_MI},	/* m */	{"pl", 2, NULL, NUM_PL},	/* p */	{"pr", 2, NULL, NUM_PR},	{"rn", 2, NULL, NUM_rn},	/* r */	{"sg", 2, NULL, NUM_SG},	/* s */	{"sp", 2, NULL, NUM_SP},	{"s", 1, NULL, NUM_S},	{"th", 2, NULL, NUM_th},	/* t */	{"v", 1, NULL, NUM_V},		/* v *//* last */{NULL, 0, NULL, 0}};/* ---------- * KeyWords index for DATE-TIME version * ---------- */static const int DCH_index[KeyWord_INDEX_SIZE] = {/*0	1	2	3	4	5	6	7	8	9*/	/*---- first 0..31 chars are skipped ----*/	-1, -1, -1, -1, -1, -1, -1, -1,	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,	-1, -1, -1, -1, -1, DCH_A_D, DCH_B_C, DCH_CC, DCH_DAY, -1,	DCH_FX, -1, DCH_HH24, DCH_IW, DCH_J, -1, -1, DCH_MI, -1, -1,	DCH_P_M, DCH_Q, DCH_RM, DCH_SSSS, DCH_TZ, DCH_US, -1, DCH_WW, -1, DCH_Y_YYY,	-1, -1, -1, -1, -1, -1, -1, DCH_a_d, DCH_b_c, DCH_cc,	DCH_day, -1, DCH_fx, -1, DCH_hh24, DCH_iw, DCH_j, -1, -1, DCH_mi,	-1, -1, DCH_p_m, DCH_q, DCH_rm, DCH_ssss, DCH_tz, DCH_us, -1, DCH_ww,	-1, DCH_y_yyy, -1, -1, -1, -1	/*---- chars over 126 are skiped ----*/};/* ---------- * KeyWords index for NUMBER version * ---------- */static const int NUM_index[KeyWord_INDEX_SIZE] = {/*0	1	2	3	4	5	6	7	8	9*/	/*---- first 0..31 chars are skiped ----*/	-1, -1, -1, -1, -1, -1, -1, -1,	-1, -1, -1, -1, NUM_COMMA, -1, NUM_DEC, -1, NUM_0, -1,	-1, -1, -1, -1, -1, -1, -1, NUM_9, -1, -1,	-1, -1, -1, -1, -1, -1, NUM_B, NUM_C, NUM_D, NUM_E,	NUM_FM, NUM_G, -1, -1, -1, -1, NUM_L, NUM_MI, -1, -1,	NUM_PL, -1, NUM_RN, NUM_SG, NUM_TH, -1, NUM_V, -1, -1, -1,	-1, -1, -1, -1, -1, -1, -1, -1, NUM_b, NUM_c,	NUM_d, NUM_e, NUM_fm, NUM_g, -1, -1, -1, -1, NUM_l, NUM_mi,	-1, -1, NUM_pl, -1, NUM_rn, NUM_sg, NUM_th, -1, NUM_v, -1,	-1, -1, -1, -1, -1, -1	/*---- chars over 126 are skiped ----*/};/* ---------- * Number processor struct * ---------- */typedef struct NUMProc{	bool		is_to_char;	NUMDesc    *Num;			/* number description		*/	int			sign,			/* '-' or '+'			*/				sign_wrote,		/* was sign write		*/				num_count,		/* number of write digits	*/				num_in,			/* is inside number		*/				num_curr,		/* current position in number	*/				num_pre,		/* space before first number	*/				read_dec,		/* to_number - was read dec. point	*/				read_post,		/* to_number - number of dec. digit */				read_pre;		/* to_number - number non-dec. digit */	char	   *number,			/* string with number	*/			   *number_p,		/* pointer to current number position */			   *inout,			/* in / out buffer	*/			   *inout_p,		/* pointer to current inout position */			   *last_relevant,	/* last relevant number after decimal point */			   *L_negative_sign,	/* Locale */			   *L_positive_sign,			   *decimal,			   *L_thousands_sep,			   *L_currency_symbol;} NUMProc;/* ---------- * Functions * ---------- */static const KeyWord *index_seq_search(char *str, const KeyWord *kw,				 const int *index);static KeySuffix *suff_search(char *str, KeySuffix *suf, int type);static void NUMDesc_prepare(NUMDesc *num, FormatNode *n);static void parse_format(FormatNode *node, char *str, const KeyWord *kw,			 KeySuffix *suf, const int *index, int ver, NUMDesc *Num);static char *DCH_processor(FormatNode *node, char *inout, bool is_to_char,			  bool is_interval, void *data);#ifdef DEBUG_TO_FROM_CHARstatic void dump_index(const KeyWord *k, const int *index);static void dump_node(FormatNode *node, int max);#endifstatic char *get_th(char *num, int type);static char *str_numth(char *dest, char *num, int type);static int	strdigits_len(char *str);static char *str_toupper(char *buff);static char *str_tolower(char *buff);/* static int is_acdc(char *str, int *len); */static int	seq_search(char *name, char **array, int type, int max, int *len);static void do_to_timestamp(text *date_txt, text *fmt,				struct pg_tm * tm, fsec_t *fsec);static char *fill_str(char *str, int c, int max);static FormatNode *NUM_cache(int len, NUMDesc *Num, char *pars_str, bool *shouldFree);static char *int_to_roman(int number);static void NUM_prepare_locale(NUMProc *Np);static char *get_last_relevant_decnum(char *num);static void NUM_numpart_from_char(NUMProc *Np, int id, int plen);static void NUM_numpart_to_char(NUMProc *Np, int id);static char *NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number,			  int plen, int sign, bool is_to_char);static DCHCacheEntry *DCH_cache_search(char *str);static DCHCacheEntry *DCH_cache_getnew(char *str);static NUMCacheEntry *NUM_cache_search(char *str);static NUMCacheEntry *NUM_cache_getnew(char *str);static void NUM_cache_remove(NUMCacheEntry *ent);/* ---------- * Fast sequential search, use index for data selection which * go to seq. cycle (it is very fast for unwanted strings) * (can't be used binary search in format parsing) * ---------- */static const KeyWord *index_seq_search(char *str, const KeyWord *kw, const int *index){	int			poz;	if (!KeyWord_INDEX_FILTER(*str))		return NULL;	if ((poz = *(index + (*str - ' '))) > -1)	{		const KeyWord *k = kw + poz;		do		{			if (!strncmp(str, k->name, k->len))				return k;			k++;			if (!k->name)				return NULL;		} while (*str == *k->name);	}	return NULL;}static KeySuffix *suff_search(char *str, KeySuffix *suf, int type){	KeySuffix  *s;	for (s = suf; s->name != NULL; s++)	{		if (s->type != type)			continue;		if (!strncmp(str, s->name, s->len))			return s;	}	return NULL;}/* ---------- * Prepare NUMDesc (number description struct) via FormatNode struct * ---------- */static voidNUMDesc_prepare(NUMDesc *num, FormatNode *n){	if (n->type != NODE_TYPE_ACTION)		return;	switch (n->key->id)	{		case NUM_9:			if (IS_BRACKET(num))			{				NUM_cache_remove(last_NUMCacheEntry);				ereport(ERROR,						(errcode(ERRCODE_SYNTAX_ERROR),						 errmsg("\"9\" must be ahead of \"PR\"")));			}			if (IS_MULTI(num))			{				++num->multi;				break;			}			if (IS_DECIMAL(num))				++num->post;			else				++num->pre;			break;		case NUM_0:			if (IS_BRACKET(num))			{				NUM_cache_remove(last_NUMCacheEntry);				ereport(ERROR,						(errcode(ERRCODE_SYNTAX_ERROR),						 errmsg("\"0\" must be ahead of \"PR\"")));			}			if (!IS_ZERO(num) && !IS_DECIMAL(num))			{				num->flag |= NUM_F_ZERO;				num->zero_start = num->pre + 1;			}			if (!IS_DECIMAL(num))				++num->pre;			else				++num->post;			num->zero_end = num->pre + num->post;			break;		case NUM_B:			if (num->pre == 0 && num->post == 0 && (!IS_ZERO(num)))				num->flag |= NUM_F_BLANK;			break;		case NUM_D:			num->flag |= NUM_F_LDECIMAL;			num->need_locale = TRUE;		case NUM_DEC:			if (IS_DECIMAL(num))			{				NUM_cache_remove(last_NUMCacheEntry);				ereport(ERROR,						(errcode(ERRCODE_SYNTAX_ERROR),						 errmsg("multiple decimal points")));			}			if (IS_MULTI(num))			{				NUM_cache_remove(last_NUMCacheEntry);				ereport(ERROR,						(errcode(ERRCODE_SYNTAX_ERROR),					 errmsg("cannot use \"V\" and decimal point together")));			}			num->flag |= NUM_F_DECIMAL;			break;		case NUM_FM:			num->flag |= NUM_F_FILLMODE;			break;		case NUM_S:			if (IS_LSIGN(num))			{				NUM_cache_remove(last_NUMCacheEntry);				ereport(ERROR,						(errcode(ERRCODE_SYNTAX_ERROR),						 errmsg("not unique \"S\"")));			}			if (IS_PLUS(num) || IS_MINUS(num) || IS_BRACKET(num))			{				NUM_cache_remove(last_NUMCacheEntry);				ereport(ERROR,						(errcode(ERRCODE_SYNTAX_ERROR),						 errmsg("cannot use \"S\" and \"PL\"/\"MI\"/\"SG\"/\"PR\" together")));			}			if (!IS_DECIMAL(num))			{				num->lsign = NUM_LSIGN_PRE;				num->pre_lsign_num = num->pre;				num->need_locale = TRUE;				num->flag |= NUM_F_LSIGN;			}			else if (num->lsign == NUM_LSIGN_NONE)			{				num->lsign = NUM_LSIGN_POST;				num->need_locale = TRUE;				num->flag |= NUM_F_LSIGN;			}			break;		case NUM_MI:			if (IS_LSIGN(num))			{				NUM_cache_remove(last_NUMCacheEntry);				ereport(ERROR,						(errcode(ERRCODE_SYNTAX_ERROR),						 errmsg("cannot use \"S\" and \"MI\" together")));			}			num->flag |= NUM_F_MINUS;			if (IS_DECIMAL(num))				num->flag |= NUM_F_MINUS_POST;			break;		case NUM_PL:			if (IS_LSIGN(num))			{				NUM_cache_remove(last_NUMCacheEntry);				ereport(ERROR,						(errcode(ERRCODE_SYNTAX_ERROR),						 errmsg("cannot use \"S\" and \"PL\" together")));			}			num->flag |= NUM_F_PLUS;			if (IS_DECIMAL(num))				num->flag |= NUM_F_PLUS_POST;			break;		case NUM_SG:			if (IS_LSIGN(num))			{				NUM_cache_remove(last_NUMCacheEntry);				ereport(ERROR,						(errcode(ERRCODE_SYNTAX_ERROR),						 errmsg("cannot use \"S\" and \"SG\" together")));			}			num->flag |= NUM_F_MINUS;			num->flag |= NUM_F_PLUS;			break;		case NUM_PR:			if (IS_LSIGN(num) || IS_PLUS(num) || IS_MINUS(num))			{				NUM_cache_remove(last_NUMCacheEntry);				ereport(ERROR,						(errcode(ERRCODE_SYNTAX_ERROR),						 errmsg("cannot use \"PR\" and \"S\"/\"PL\"/\"MI\"/\"SG\" together")));			}			num->flag |= NUM_F_BRACKET;			break;		case NUM_rn:		case NUM_RN:			num->flag |= NUM_F_ROMAN;			break;		case NUM_L:		case NUM_G:			num->need_locale = TRUE;			break;		case NUM_V:			if (IS_DECIMAL(num))			{				NUM_cache_remove(last_NUMCacheEntry);				ereport(ERROR,						(errcode(ERRCODE_SYNTAX_ERROR),					 errmsg("cannot use \"V\" and decimal point together")));			}			num->flag |= NUM_F_MULTI;			break;		case NUM_E:			NUM_cache_remove(last_NUMCacheEntry);			ereport(ERROR,					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),					 errmsg("\"E\" is not supported")));	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -