formatting.c

来自「PostgreSQL7.4.6 for Linux」· C语言 代码 · 共 2,989 行 · 第 1/5 页

C
2,989
字号
			/*			 * 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 = (KeyWord *) 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 = (KeyWord *) 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, int flag, void *data){	FormatNode *n;	char	   *s;	/*	 * Zeroing global flags	 */	DCH_global_flag = 0;	for (n = node, s = inout; n->type != NODE_TYPE_END; n++)	{		if (flag == FROM_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, flag, n, data);			if (len > 0)				s += len;			else if (len == -1)				continue;		}		else		{			/*			 * Remove to output char from input in TO_CHAR			 */			if (flag == TO_CHAR)				*s = n->character;			else			{				/*				 * Skip blank space in FROM_CHAR's input				 */				if (isspace((unsigned char) n->character) && IS_FX == 0)				{					while (*s != '\0' && isspace((unsigned char) *(s + 1)))						++s;				}			}		}				++s;					/* ! */	}	if (flag == 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){	sprintf(dest, "%s%s", num, 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 = 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 = 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 = toupper((unsigned char) *name);	else if (type == ALL_LOWER)		*name = 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 = tolower((unsigned char) *n);				else if (type == ALL_UPPER)					*n = 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(KeyWord *k, 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, int flag, FormatNode *node, void *data){	if (arg == DCH_FX)		DCH_global_flag |= DCH_F_FX;	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, int flag, FormatNode *node, void *data){	char	   *p_inout = inout;	struct tm  *tm = NULL;	TmFromChar *tmfc = NULL;	TmToChar   *tmtc = NULL;	if (flag == TO_CHAR)	{		tmtc = (TmToChar *) data;		tm = tmtcTm(tmtc);	}	else		tmfc = (TmFromChar *) data;	switch (arg)	{		case DCH_A_M:		case DCH_P_M:			if (flag == TO_CHAR)			{				strcpy(inout, ((tm->tm_hour > 11							  && tm->tm_hour < 24) ? P_M_STR : A_M_STR));				return 3;			}			else if (flag == FROM_CHAR)			{				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 3;			}			break;		case DCH_AM:		case DCH_PM:			if (flag == TO_CHAR)			{				strcpy(inout, ((tm->tm_hour > 11								&& tm->tm_hour < 24) ? PM_STR : AM_STR));				return 1;			}			else if (flag == FROM_CHAR)			{				if (strncmp(inout, PM_STR, 2) == 0)					tmfc->pm = TRUE;				else if (strncmp(inout, AM_STR, 2) == 0)					tmfc->am = TRUE;				else					AMPM_ERROR;				return 1;			}			break;		case DCH_a_m:		case DCH_p_m:			if (flag == TO_CHAR)			{				strcpy(inout, ((tm->tm_hour > 11							  && tm->tm_hour < 24) ? p_m_STR : a_m_STR));				return 3;			}			else if (flag == FROM_CHAR)			{				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 3;			}			break;		case DCH_am:		case DCH_pm:			if (flag == TO_CHAR)			{				strcpy(inout, ((tm->tm_hour > 11								&& tm->tm_hour < 24) ? pm_STR : am_STR));				return 1;			}			else if (flag == FROM_CHAR)			{				if (strncmp(inout, pm_STR, 2) == 0)					tmfc->pm = TRUE;				else if (strncmp(inout, am_STR, 2) == 0)					tmfc->am = TRUE;				else					AMPM_ERROR;				return 1;			}			break;		case DCH_HH:		case DCH_HH12:			if (flag == TO_CHAR)			{				sprintf(inout, "%0*d", S_FM(suf) ? 0 : 2,						tm->tm_hour == 0 ? 12 :					  tm->tm_hour < 13 ? tm->tm_hour : tm->tm_hour - 12);				if (S_THth(suf))					str_numth(p_inout, inout, 0);				if (S_FM(suf) || S_THth(suf))					return strlen(p_inout) - 1;				else					return 1;			}			else if (flag == FROM_CHAR)			{				if (S_FM(suf) || is_next_separator(node))				{					sscanf(inout, "%d", &tmfc->hh);					return strdigits_len(inout) - 1 + SKIP_THth(suf);				}				else

⌨️ 快捷键说明

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