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

📄 formatting.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 5 页
字号:
	return;}/* ---------- * Format parser, search small keywords and keyword's suffixes, and make * format-node tree. * * for DATE-TIME & NUMBER version * ---------- */static voidparse_format(FormatNode *node, char *str, const KeyWord *kw,			 KeySuffix *suf, const int *index, int ver, NUMDesc *Num){	KeySuffix  *s;	FormatNode *n;	int			node_set = 0,				suffix,				last = 0;#ifdef DEBUG_TO_FROM_CHAR	elog(DEBUG_elog_output, "to_char/number(): run parser");#endif	n = node;	while (*str)	{		suffix = 0;		/*		 * Prefix		 */		if (ver == DCH_TYPE && (s = suff_search(str, suf, SUFFTYPE_PREFIX)) != NULL)		{			suffix |= s->id;			if (s->len)				str += s->len;		}		/*		 * Keyword		 */		if (*str && (n->key = index_seq_search(str, kw, index)) != NULL)		{			n->type = NODE_TYPE_ACTION;			n->suffix = 0;			node_set = 1;			if (n->key->len)				str += n->key->len;			/*			 * NUM version: Prepare global NUMDesc struct			 */			if (ver == NUM_TYPE)				NUMDesc_prepare(Num, n);			/*			 * Postfix			 */			if (ver == DCH_TYPE && *str && (s = suff_search(str, suf, SUFFTYPE_POSTFIX)) != NULL)			{				suffix |= s->id;				if (s->len)					str += s->len;			}		}		else if (*str)		{			/*			 * Special characters '\' and '"'			 */			if (*str == '"' && last != '\\')			{				int			x = 0;				while (*(++str))				{					if (*str == '"' && x != '\\')					{						str++;						break;					}					else if (*str == '\\' && x != '\\')					{						x = '\\';						continue;					}					n->type = NODE_TYPE_CHAR;					n->character = *str;					n->key = NULL;					n->suffix = 0;					++n;					x = *str;				}				node_set = 0;				suffix = 0;				last = 0;			}			else if (*str && *str == '\\' && last != '\\' && *(str + 1) == '"')			{				last = *str;				str++;			}			else if (*str)			{				n->type = NODE_TYPE_CHAR;				n->character = *str;				n->key = NULL;				node_set = 1;				last = 0;				str++;			}		}		/* end */		if (node_set)		{			if (n->type == NODE_TYPE_ACTION)				n->suffix = suffix;			++n;			n->suffix = 0;			node_set = 0;		}	}	n->type = NODE_TYPE_END;	n->suffix = 0;	return;}/* ---------- * Call keyword's function for each of (action) node in format-node tree * ---------- */static char *DCH_processor(FormatNode *node, char *inout, bool is_to_char,			  bool is_interval, void *data){	FormatNode *n;	char	   *s;	/*	 * Zeroing global flags	 */	DCH_global_fx = false;	for (n = node, s = inout; n->type != NODE_TYPE_END; n++)	{		if (!is_to_char && *s == '\0')			/*			 * The input string is shorter than format picture, so it's good			 * time to break this loop...			 *			 * Note: this isn't relevant for TO_CHAR mode, beacuse it use			 * 'inout' allocated by format picture length.			 */			break;		if (n->type == NODE_TYPE_ACTION)		{			int			len;			/*			 * Call node action function			 */			len = n->key->action(n->key->id, s, n->suffix, is_to_char,								 is_interval, n, data);			if (len > 0)				s += len - 1;	/* s++ is at the end of the loop */			else if (len == -1)				continue;		}		else		{			/*			 * Remove to output char from input in TO_CHAR			 */			if (is_to_char)				*s = n->character;			else			{				/*				 * Skip blank space in FROM_CHAR's input				 */				if (isspace((unsigned char) n->character) && !DCH_global_fx)					while (*s != '\0' && isspace((unsigned char) *(s + 1)))						++s;			}		}		++s;	}	if (is_to_char)		*s = '\0';	return inout;}/* ---------- * DEBUG: Dump the FormatNode Tree (debug) * ---------- */#ifdef DEBUG_TO_FROM_CHAR#define DUMP_THth(_suf) (S_TH(_suf) ? "TH" : (S_th(_suf) ? "th" : " "))#define DUMP_FM(_suf)	(S_FM(_suf) ? "FM" : " ")static voiddump_node(FormatNode *node, int max){	FormatNode *n;	int			a;	elog(DEBUG_elog_output, "to_from-char(): DUMP FORMAT");	for (a = 0, n = node; a <= max; n++, a++)	{		if (n->type == NODE_TYPE_ACTION)			elog(DEBUG_elog_output, "%d:\t NODE_TYPE_ACTION '%s'\t(%s,%s)",				 a, n->key->name, DUMP_THth(n->suffix), DUMP_FM(n->suffix));		else if (n->type == NODE_TYPE_CHAR)			elog(DEBUG_elog_output, "%d:\t NODE_TYPE_CHAR '%c'", a, n->character);		else if (n->type == NODE_TYPE_END)		{			elog(DEBUG_elog_output, "%d:\t NODE_TYPE_END", a);			return;		}		else			elog(DEBUG_elog_output, "%d:\t unknown NODE!", a);	}}#endif   /* DEBUG *//***************************************************************************** *			Private utils *****************************************************************************//* ---------- * Return ST/ND/RD/TH for simple (1..9) numbers * type --> 0 upper, 1 lower * ---------- */static char *get_th(char *num, int type){	int			len = strlen(num),				last,				seclast;	last = *(num + (len - 1));	if (!isdigit((unsigned char) last))		ereport(ERROR,				(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),				 errmsg("\"%s\" is not a number", num)));	/*	 * All "teens" (<x>1[0-9]) get 'TH/th', while <x>[02-9][123] still get	 * 'ST/st', 'ND/nd', 'RD/rd', respectively	 */	if ((len > 1) && ((seclast = num[len - 2]) == '1'))		last = 0;	switch (last)	{		case '1':			if (type == TH_UPPER)				return numTH[0];			return numth[0];		case '2':			if (type == TH_UPPER)				return numTH[1];			return numth[1];		case '3':			if (type == TH_UPPER)				return numTH[2];			return numth[2];		default:			if (type == TH_UPPER)				return numTH[3];			return numth[3];	}	return NULL;}/* ---------- * Convert string-number to ordinal string-number * type --> 0 upper, 1 lower * ---------- */static char *str_numth(char *dest, char *num, int type){	if (dest != num)		strcpy(dest, num);	strcat(dest, get_th(num, type));	return dest;}/* ---------- * Convert string to upper-string. Input string is modified in place. * ---------- */static char *str_toupper(char *buff){	char	   *p_buff = buff;	if (!buff)		return NULL;	while (*p_buff)	{		*p_buff = pg_toupper((unsigned char) *p_buff);		++p_buff;	}	return buff;}/* ---------- * Convert string to lower-string. Input string is modified in place. * ---------- */static char *str_tolower(char *buff){	char	   *p_buff = buff;	if (!buff)		return NULL;	while (*p_buff)	{		*p_buff = pg_tolower((unsigned char) *p_buff);		++p_buff;	}	return buff;}/* ---------- * Sequential search with to upper/lower conversion * ---------- */static intseq_search(char *name, char **array, int type, int max, int *len){	char	   *p,			   *n,			  **a;	int			last,				i;	*len = 0;	if (!*name)		return -1;	/* set first char */	if (type == ONE_UPPER || type == ALL_UPPER)		*name = pg_toupper((unsigned char) *name);	else if (type == ALL_LOWER)		*name = pg_tolower((unsigned char) *name);	for (last = 0, a = array; *a != NULL; a++)	{		/* comperate first chars */		if (*name != **a)			continue;		for (i = 1, p = *a + 1, n = name + 1;; n++, p++, i++)		{			/* search fragment (max) only */			if (max && i == max)			{				*len = i;				return a - array;			}			/* full size */			if (*p == '\0')			{				*len = i;				return a - array;			}			/* Not found in array 'a' */			if (*n == '\0')				break;			/*			 * Convert (but convert new chars only)			 */			if (i > last)			{				if (type == ONE_UPPER || type == ALL_LOWER)					*n = pg_tolower((unsigned char) *n);				else if (type == ALL_UPPER)					*n = pg_toupper((unsigned char) *n);				last = i;			}#ifdef DEBUG_TO_FROM_CHAR			/*			 * elog(DEBUG_elog_output, "N: %c, P: %c, A: %s (%s)", *n, *p, *a,			 * name);			 */#endif			if (*n != *p)				break;		}	}	return -1;}#ifdef DEBUG_TO_FROM_CHAR/* ----------- * DEBUG: Call for debug and for index checking; (Show ASCII char * and defined keyword for each used position * ---------- */static voiddump_index(const KeyWord *k, const int *index){	int			i,				count = 0,				free_i = 0;	elog(DEBUG_elog_output, "TO-FROM_CHAR: Dump KeyWord Index:");	for (i = 0; i < KeyWord_INDEX_SIZE; i++)	{		if (index[i] != -1)		{			elog(DEBUG_elog_output, "\t%c: %s, ", i + 32, k[index[i]].name);			count++;		}		else		{			free_i++;			elog(DEBUG_elog_output, "\t(%d) %c %d", i, i + 32, index[i]);		}	}	elog(DEBUG_elog_output, "\n\t\tUsed positions: %d,\n\t\tFree positions: %d",		 count, free_i);}#endif   /* DEBUG *//* ---------- * Skip TM / th in FROM_CHAR * ---------- */#define SKIP_THth(_suf)		(S_THth(_suf) ? 2 : 0)/* ---------- * Global format option for DCH version * ---------- */static intdch_global(int arg, char *inout, int suf, bool is_to_char, bool is_interval,		   FormatNode *node, void *data){	if (arg == DCH_FX)		DCH_global_fx = true;	return -1;}/* ---------- * Return TRUE if next format picture is not digit value * ---------- */static boolis_next_separator(FormatNode *n){	if (n->type == NODE_TYPE_END)		return FALSE;	if (n->type == NODE_TYPE_ACTION && S_THth(n->suffix))		return TRUE;	/*	 * Next node	 */	n++;	if (n->type == NODE_TYPE_END)		return FALSE;	if (n->type == NODE_TYPE_ACTION)	{		if (n->key->isitdigit)			return FALSE;		return TRUE;	}	else if (isdigit((unsigned char) n->character))		return FALSE;	return TRUE;				/* some non-digit input (separator) */}static intstrdigits_len(char *str){	char	   *p = str;	int			len = 0;	while (*p && isdigit((unsigned char) *p) && len <= DCH_MAX_ITEM_SIZ)	{		len++;		p++;	}	return len;}#define AMPM_ERROR	ereport(ERROR, \							(errcode(ERRCODE_INVALID_DATETIME_FORMAT), \							 errmsg("invalid AM/PM string")));/* ---------- * Master function of TIME for: *			  TO_CHAR	- write (inout) formated string *			  FROM_CHAR - scan (inout) string by course of FormatNode * ---------- */static intdch_time(int arg, char *inout, int suf, bool is_to_char, bool is_interval,		 FormatNode *node, void *data){	char	   *p_inout = inout;	struct pg_tm *tm = NULL;	TmFromChar *tmfc = NULL;	TmToChar   *tmtc = NULL;	if (is_to_char)	{		tmtc = (TmToChar *) data;		tm = tmtcTm(tmtc);	}	else		tmfc = (TmFromChar *) data;	switch (arg)	{		case DCH_A_M:		case DCH_P_M:			if (is_to_char)			{				strcpy(inout, (tm->tm_hour % HOURS_PER_DAY >= HOURS_PER_DAY / 2)					   ? P_M_STR : A_M_STR);				return strlen(p_inout);			}			else			{				if (strncmp(inout, P_M_STR, 4) == 0)					tmfc->pm = TRUE;				else if (strncmp(inout, A_M_STR, 4) == 0)					tmfc->am = TRUE;				else					AMPM_ERROR;				return strlen(p_inout);			}			break;		case DCH_AM:		case DCH_PM:			if (is_to_char)			{				strcpy(inout, (tm->tm_hour % HOURS_PER_DAY >= HOURS_PER_DAY / 2)					   ? PM_STR : AM_STR);				return strlen(p_inout);

⌨️ 快捷键说明

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