diff options
Diffstat (limited to 'src/backend/nodes/read.c')
-rw-r--r-- | src/backend/nodes/read.c | 421 |
1 files changed, 226 insertions, 195 deletions
diff --git a/src/backend/nodes/read.c b/src/backend/nodes/read.c index 7e89f9d74d3..f0baa4f14d7 100644 --- a/src/backend/nodes/read.c +++ b/src/backend/nodes/read.c @@ -1,18 +1,18 @@ /*------------------------------------------------------------------------- * * read.c-- - * routines to convert a string (legal ascii representation of node) back - * to nodes + * routines to convert a string (legal ascii representation of node) back + * to nodes * * Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/read.c,v 1.3 1997/08/12 22:53:04 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/read.c,v 1.4 1997/09/07 04:42:56 momjian Exp $ * * HISTORY - * AUTHOR DATE MAJOR EVENT - * Andrew Yu Nov 2, 1994 file creation + * AUTHOR DATE MAJOR EVENT + * Andrew Yu Nov 2, 1994 file creation * *------------------------------------------------------------------------- */ @@ -26,17 +26,17 @@ /* * stringToNode - - * returns a Node with a given legal ascii representation + * returns a Node with a given legal ascii representation */ -void * +void * stringToNode(char *str) { - void *retval; + void *retval; - lsptok(str, NULL); /* set the string used in lsptok */ - retval = nodeRead(true); /* start reading */ + lsptok(str, NULL); /* set the string used in lsptok */ + retval = nodeRead(true); /* start reading */ - return retval; + return retval; } /***************************************************************************** @@ -46,115 +46,126 @@ stringToNode(char *str) *****************************************************************************/ #define RIGHT_PAREN (1000000 + 1) -#define LEFT_PAREN (1000000 + 2) -#define PLAN_SYM (1000000 + 3) -#define AT_SYMBOL (1000000 + 4) -#define ATOM_TOKEN (1000000 + 5) +#define LEFT_PAREN (1000000 + 2) +#define PLAN_SYM (1000000 + 3) +#define AT_SYMBOL (1000000 + 4) +#define ATOM_TOKEN (1000000 + 5) /* * nodeTokenType - - * returns the type of the node token contained in token. - * It returns one of the following valid NodeTags: - * T_Integer, T_Float, T_String - * and some of its own: - * RIGHT_PAREN, LEFT_PAREN, PLAN_SYM, AT_SYMBOL, ATOM_TOKEN + * returns the type of the node token contained in token. + * It returns one of the following valid NodeTags: + * T_Integer, T_Float, T_String + * and some of its own: + * RIGHT_PAREN, LEFT_PAREN, PLAN_SYM, AT_SYMBOL, ATOM_TOKEN * - * Assumption: the ascii representation is legal + * Assumption: the ascii representation is legal */ -static NodeTag +static NodeTag nodeTokenType(char *token, int length) { - NodeTag retval = 0; - - /* - * Check if the token is a number (decimal or integer, - * positive or negative - */ - if (isdigit(*token) || - (length>=2 && *token=='-' && isdigit(*(token+1)) )) + NodeTag retval = 0; + + /* + * Check if the token is a number (decimal or integer, positive or + * negative + */ + if (isdigit(*token) || + (length >= 2 && *token == '-' && isdigit(*(token + 1)))) { - /* - * skip the optional '-' (i.e. negative number) - */ - if (*token == '-') { - token++; - } - - /* - * See if there is a decimal point - */ - - for (; length && *token != '.'; token++, length--); - - /* - * if there isn't, token's an int, otherwise it's a float. - */ - - retval = (*token != '.') ? T_Integer : T_Float; + + /* + * skip the optional '-' (i.e. negative number) + */ + if (*token == '-') + { + token++; + } + + /* + * See if there is a decimal point + */ + + for (; length && *token != '.'; token++, length--); + + /* + * if there isn't, token's an int, otherwise it's a float. + */ + + retval = (*token != '.') ? T_Integer : T_Float; } - else if (isalpha(*token)) - retval = ATOM_TOKEN; - else if (*token == '(') - retval = LEFT_PAREN; - else if (*token == ')') - retval = RIGHT_PAREN; - else if (*token == '@') - retval = AT_SYMBOL; - else if (*token == '\"') - retval = T_String; - else if (*token == '{') - retval = PLAN_SYM; - return(retval); + else if (isalpha(*token)) + retval = ATOM_TOKEN; + else if (*token == '(') + retval = LEFT_PAREN; + else if (*token == ')') + retval = RIGHT_PAREN; + else if (*token == '@') + retval = AT_SYMBOL; + else if (*token == '\"') + retval = T_String; + else if (*token == '{') + retval = PLAN_SYM; + return (retval); } /* * Works kinda like strtok, except it doesn't put nulls into string. - * + * * Returns the length in length instead. The string can be set without * returning a token by calling lsptok with length == NULL. * */ -char * +char * lsptok(char *string, int *length) { - static char *local_str; - char *ret_string; - - if (string != NULL) { - local_str = string; - if (length == NULL) { - return(NULL); + static char *local_str; + char *ret_string; + + if (string != NULL) + { + local_str = string; + if (length == NULL) + { + return (NULL); + } + } + + for (; *local_str == ' ' + || *local_str == '\n' + || *local_str == '\t'; local_str++); + + /* + * Now pointing at next token. + */ + ret_string = local_str; + if (*local_str == '\0') + return (NULL); + *length = 1; + + if (*local_str == '\"') + { + for (local_str++; *local_str != '\"'; (*length)++, local_str++); + (*length)++; + local_str++; + } + else if (*local_str == ')' || *local_str == '(' || + *local_str == '}' || *local_str == '{') + { + local_str++; + } + else + { + for (; *local_str != ' ' + && *local_str != '\n' + && *local_str != '\t' + && *local_str != '{' + && *local_str != '}' + && *local_str != '(' + && *local_str != ')'; local_str++, (*length)++); + (*length)--; } - } - - for (; *local_str == ' ' - || *local_str == '\n' - || *local_str == '\t'; local_str++); - - /* - * Now pointing at next token. - */ - ret_string = local_str; - if (*local_str == '\0') return(NULL); - *length = 1; - - if (*local_str == '\"') { - for (local_str++; *local_str != '\"'; (*length)++, local_str++); - (*length)++; local_str++; - }else if (*local_str == ')' || *local_str == '(' || - *local_str == '}' || *local_str == '{') { - local_str++; - }else { - for (; *local_str != ' ' - && *local_str != '\n' - && *local_str != '\t' - && *local_str != '{' - && *local_str != '}' - && *local_str != '(' - && *local_str != ')'; local_str++, (*length)++); - (*length)--; - } - return(ret_string); + return (ret_string); } /* @@ -163,108 +174,128 @@ lsptok(char *string, int *length) * Secrets: He assumes that lsptok already has the string (see below). * Any callers should set read_car_only to true. */ -void * +void * nodeRead(bool read_car_only) { - char *token; - NodeTag type; - Node *this_value = NULL, *return_value = NULL; - int tok_len; - char tmp; - bool make_dotted_pair_cell = false; - - token = lsptok(NULL, &tok_len); - - if (token == NULL) return(NULL); - - type = nodeTokenType(token, tok_len); - - switch(type) { - case PLAN_SYM: - this_value = parsePlanString(); + char *token; + NodeTag type; + Node *this_value = NULL, + *return_value = NULL; + int tok_len; + char tmp; + bool make_dotted_pair_cell = false; + token = lsptok(NULL, &tok_len); - if (token[0] != '}') return(NULL); - if (!read_car_only) - make_dotted_pair_cell = true; - else - make_dotted_pair_cell = false; - break; - case LEFT_PAREN: - if (!read_car_only) { - List *l = makeNode(List); + if (token == NULL) + return (NULL); - lfirst(l) = nodeRead(false); - lnext(l) = nodeRead(false); - this_value = (Node*)l; - }else { - this_value = nodeRead(false); - } - break; - case RIGHT_PAREN: - this_value = NULL; - break; - case AT_SYMBOL: - break; - case ATOM_TOKEN: - if (!strncmp(token, "nil", 3)) { - this_value = NULL; - /* - * It might be "nil" but it is an atom! - */ - if (read_car_only) { - make_dotted_pair_cell = false; - } else { + type = nodeTokenType(token, tok_len); + + switch (type) + { + case PLAN_SYM: + this_value = parsePlanString(); + token = lsptok(NULL, &tok_len); + if (token[0] != '}') + return (NULL); + + if (!read_car_only) + make_dotted_pair_cell = true; + else + make_dotted_pair_cell = false; + break; + case LEFT_PAREN: + if (!read_car_only) + { + List *l = makeNode(List); + + lfirst(l) = nodeRead(false); + lnext(l) = nodeRead(false); + this_value = (Node *) l; + } + else + { + this_value = nodeRead(false); + } + break; + case RIGHT_PAREN: + this_value = NULL; + break; + case AT_SYMBOL: + break; + case ATOM_TOKEN: + if (!strncmp(token, "nil", 3)) + { + this_value = NULL; + + /* + * It might be "nil" but it is an atom! + */ + if (read_car_only) + { + make_dotted_pair_cell = false; + } + else + { + make_dotted_pair_cell = true; + } + } + else + { + tmp = token[tok_len]; + token[tok_len] = '\0'; + this_value = (Node *) pstrdup(token); /* !attention! not a + * Node. use with + * caution */ + token[tok_len] = tmp; + make_dotted_pair_cell = true; + } + break; + case T_Float: + tmp = token[tok_len]; + token[tok_len] = '\0'; + this_value = (Node *) makeFloat(atof(token)); + token[tok_len] = tmp; + make_dotted_pair_cell = true; + break; + case T_Integer: + tmp = token[tok_len]; + token[tok_len] = '\0'; + this_value = (Node *) makeInteger(atoi(token)); + token[tok_len] = tmp; make_dotted_pair_cell = true; - } - }else { - tmp = token[tok_len]; - token[tok_len] = '\0'; - this_value = (Node*)pstrdup(token); /* !attention! not a Node. - use with caution */ - token[tok_len] = tmp; - make_dotted_pair_cell = true; + break; + case T_String: + tmp = token[tok_len - 1]; + token[tok_len - 1] = '\0'; + token++; + this_value = (Node *) makeString(token); /* !! not strdup'd */ + token[tok_len - 2] = tmp; + make_dotted_pair_cell = true; + break; + default: + elog(WARN, "nodeRead: Bad type %d", type); + break; } - break; - case T_Float: - tmp = token[tok_len]; - token[tok_len] = '\0'; - this_value = (Node*)makeFloat(atof(token)); - token[tok_len] = tmp; - make_dotted_pair_cell = true; - break; - case T_Integer: - tmp = token[tok_len]; - token[tok_len] = '\0'; - this_value = (Node*)makeInteger(atoi(token)); - token[tok_len] = tmp; - make_dotted_pair_cell = true; - break; - case T_String: - tmp = token[tok_len - 1]; - token[tok_len - 1] = '\0'; - token++; - this_value = (Node*)makeString(token); /* !! not strdup'd */ - token[tok_len - 2] = tmp; - make_dotted_pair_cell = true; - break; - default: - elog(WARN, "nodeRead: Bad type %d", type); - break; - } - if (make_dotted_pair_cell) { - List *l = makeNode(List); + if (make_dotted_pair_cell) + { + List *l = makeNode(List); - lfirst(l) = this_value; - if (!read_car_only) { - lnext(l) = nodeRead(false); - }else { - lnext(l) = NULL; + lfirst(l) = this_value; + if (!read_car_only) + { + lnext(l) = nodeRead(false); + } + else + { + lnext(l) = NULL; + } + return_value = (Node *) l; } - return_value = (Node*)l; - }else { - return_value = this_value; - } - return(return_value); + else + { + return_value = this_value; + } + return (return_value); } - |