Beispiel #1
0
static bool
replace_variables(char **text, int lineno)
{
	bool		string = false;
	int			counter = 1,
				ptr = 0;

	for (; (*text)[ptr] != '\0'; ptr++)
	{
		if ((*text)[ptr] == '\'')
			string = string ? false : true;

		if (string || (((*text)[ptr] != ':') && ((*text)[ptr] != '?')))
			continue;

		if (((*text)[ptr] == ':') && ((*text)[ptr + 1] == ':'))
			ptr += 2;			/* skip  '::' */
		else
		{
			/* a rough guess of the size we need: */
			int			buffersize = sizeof(int) * CHAR_BIT * 10 / 3;
			int			len;
			char	   *buffer,
					   *newcopy;

			if (!(buffer = (char *) ecpg_alloc(buffersize, lineno)))
				return false;

			snprintf(buffer, buffersize, "$%d", counter++);

			for (len = 1; (*text)[ptr + len] && isvarchar((*text)[ptr + len]); len++)
				 /* skip */ ;
			if (!(newcopy = (char *) ecpg_alloc(strlen(*text) -len + strlen(buffer) + 1, lineno)))
			{
				ecpg_free(buffer);
				return false;
			}

			memcpy(newcopy, *text, ptr);
			strcpy(newcopy + ptr, buffer);
			strcat(newcopy, (*text) +ptr + len);

			ecpg_free(*text);
			ecpg_free(buffer);

			*text = newcopy;

			if ((*text)[ptr] == '\0')	/* we reached the end */
				ptr--;			/* since we will (*text)[ptr]++ in the top
								 * level for loop */
		}
	}
	return true;
}
Beispiel #2
0
int
xk_parse(
        memtbl_t *tbl,
        char **buf,
        char *p,
        int nptr,
        int sub,
        void *pass,
        memtbl_t *(*tbl_find)() )
{
	memtbl_t *ntbl;
	register int i = 0;
	int skind, delim_type;
	long val = 0;		/* used for choice selection */
	char *np;
	int delim = _Delim;
	int nmal;		/* number of members malloc'ed arrays */
	char *pp;
	int (*spec_parse)();
        char * errmsg;

	if (tbl == NULL) {
		if (_Prdebug)
                {
                   errmsg=strdup(GETMESSAGE(8,1, 
                       "xk_parse: A NULL 'type' table was specified\n"));
	 	   fprintf(stderr, errmsg);
                   free(errmsg);
                }
		return(FAIL);
	}
	xk_skipwhite(buf);
	/*
	 * If this is supposed to be a pointer, and we have a string that
	 * starts with "P" and a number then we should take the pointer
	 * itself. This is done by stripping off the 'p' and parsing it as a
	 * unsigned long.
	 *
	 * Further, if it starts with an '&', then we want the address of
	 * a variable, use fsym() to find it.
	 */
	if (((tbl->flags & F_TYPE_IS_PTR) || ((tbl->ptr + nptr) > 0)) &&
		(((UPPER((*buf)[0]) == 'P') && isdigit((*buf)[1])) || ((*buf)[0] == '&'))) {
		if ((*buf)[0] == '&') {
			char *start;

			(*buf)++;
			for (start = *buf; isvarchar(*buf[0]); (*buf)++)
				;
			if ((((unsigned long *) p)[0] = fsym(start, -1)) == NULL)
				return(FAIL);
		}
		else {
			(*buf)++;
			RIF(xk_par_int(buf, (long *)p, pass));
		}
		if (Ndont == Sdont) {
			if (Dont)
				Dont = (char **) realloc(Dont, (Sdont + 20) * sizeof(char *));
			else
				Dont = (char **) malloc((Sdont + 20) * sizeof(char *));
			if (!Dont) {
                           errmsg = strdup(GetSharedMsg(DT_ALLOC_FAILURE));
			   ALTPUTS(errmsg);
                           free(errmsg);
			   exit(1);
			}
			Sdont += 20;
		}
		Dont[Ndont++] = ((char **) p)[0];
		return(SUCCESS);
	}
	if (tbl->tname && (spec_parse = find_special(SPEC_PARSE, tbl->tname)))
		return(spec_parse(tbl, buf, p, nptr, sub, pass, tbl_find));
	if (tbl->name && (spec_parse = find_special(SPEC_PARSE, tbl->name)))
		return(spec_parse(tbl, buf, p, nptr, sub, pass, tbl_find));
	nptr += tbl->ptr;
	if (sub > 0 && tbl->subscr > 0) {
		if (_Prdebug)
                {
		   errmsg=strdup(GETMESSAGE(8,2, 
                         "xk_parse: Multiple array subscripts are not handled in '%s'\n"));
		   fprintf(stderr, errmsg, tbl->name);
                   free(errmsg);
                }
		return(FAIL);
	}
	/*
	 * If there is exactly one pointer associated with this
	 * member, and no length delimiters, and no subscripts,
	 * or there are multiple pointers,
	 * then malloc space for the structure and call ourself
	 * recursively.
	 */
	if ((nptr > 1 && tbl->delim != 0) || (nptr == 1 && tbl->delim == 0 && tbl->subscr == 0)) {
		if (PARPEEK(buf, ",") || PARPEEK(buf, Str_close_curly)) {
			((char **)p)[0] = NULL;
			if (_Prdebug)
                        {
			   errmsg=strdup(GetSharedMsg(DT_XK_PARSE_SET_NULL));
			   fprintf(stderr, errmsg, tbl->name);
                           free(errmsg);
                        }
			return(SUCCESS);
		}
			if (xk_parpeek(buf, "NULL")) {
				RIF(xk_parexpect(buf, "NULL"));
				((char **)p)[0] = NULL;
				if (_Prdebug)
                                {
			           errmsg=strdup(GetSharedMsg(
                                                 DT_XK_PARSE_SET_NULL));
				   fprintf(stderr, errmsg, tbl->name);
                                   free(errmsg);
                                }
				return(SUCCESS);
			}

		if ((((char **)p)[0] = malloc(tbl->size)) == NULL) {
			return(FAIL);
		}
		if (_Prdebug)
                {
		   errmsg=strdup(GETMESSAGE(8,3, 
                        "xk_parse: Setting '%s' to malloc'ed address 0x%x, of size %d\n"));
		   fprintf(stderr,errmsg,tbl->name, ((char **)p)[0], tbl->size);
                   free(errmsg);
                }
		return(xk_parse(tbl, buf, ((char **)p)[0], nptr-1-tbl->ptr, sub, pass, tbl_find));
	}
	/*
	 * If there is exactly one pointer level, or one subscripting level,
	 * and there is a delimiter,
	 * and no subscript, then we are a length delimited malloced array.
	 */
	xk_skipwhite(buf);
	if (tbl->delim != 0 && ((nptr == 1 && tbl->subscr == 0) ||
		(nptr == 0 && tbl->subscr != 0 && tbl->kind != K_STRING))) {

		if (tbl->subscr == 0) {
			if (PARPEEK(buf, ",") || PARPEEK(buf, Str_close_curly)) {
				((char **)p)[0] = NULL;
				if (_Prdebug)
                                {
				   errmsg=strdup(GETMESSAGE(8,4, 
                                     "xk_parse: Setting malloc'ed array '%s' to NULL\n"));
				   fprintf(stderr, errmsg, tbl->name);
                                   free(errmsg);
                                }
				return(SUCCESS);
			}
			if (xk_parpeek(buf, "NULL")) {
				RIF(xk_parexpect(buf, "NULL"));
				((char **)p)[0] = NULL;
				if (_Prdebug)
                                {
				   errmsg=strdup(GetSharedMsg(
                                                    DT_XK_PARSE_SET_NULL));
				   fprintf(stderr, errmsg, tbl->name);
                                   free(errmsg);
                                }
				return(SUCCESS);
			}
			nmal = MALMEMBERS;
			if ((np = malloc(nmal*tbl->size)) == NULL) {
				return(FAIL);
			}
			((char **)p)[0] = np;
			if (_Prdebug)
                        {
			   errmsg=strdup(GETMESSAGE(8,5, 
                                "xk_parse: Setting member '%s' to malloc'ed pointer 0x%x, of size %d\n"));
			   fprintf(stderr, errmsg, tbl->name, np, 4*tbl->size);
                           free(errmsg);
                        }
		} else {
			np = p;
		}
		xk_skipwhite(buf);
		RIF(PAREXPECT(buf, Str_open_curly));
		*buf += 1;
		i = 0;
		xk_skipwhite(buf);
		while (PARPEEK(buf, Str_close_curly) == FALSE) {
			if (tbl->subscr == 0 && i >= nmal) {
				nmal += MALMEMBERS;
				if((np = realloc(np, nmal*tbl->size)) == NULL) {
					return(FAIL);
				}
				((char **)p)[0] = np;
				if (_Prdebug) {
				   errmsg=strdup(GetSharedMsg(
                                             DT_XK_PARSE_ARRAY_OVERFLOW));
				   fprintf(stderr, errmsg, tbl->name, nmal, nmal*tbl->size);
                                   free(errmsg);
				}
			} else if (tbl->subscr > 0 && i > tbl->subscr) {
				if (_Prdebug)
                                {
				   errmsg=strdup(GETMESSAGE(8,6, 
                                          "xk_parse: The array '%s' overflowed at element number %d\n"));
				   fprintf(stderr, errmsg, tbl->name, i);
                                   free(errmsg);
                                }
			}
			if (_Prdebug)
                        {
			   errmsg=strdup(GETMESSAGE(8,7, 
                                 "xk_parse: Parsing array element [%d] of '%s' into address 0x%x\n"));
			   fprintf(stderr, errmsg, i, tbl->name, &np[i*tbl->size]);
                           free(errmsg);
                        }
			if (i) {
				xk_skipwhite(buf);
				if (PARPEEK(buf, ",") == FALSE) {
					if (PARPEEK(buf, Str_close_curly) == FALSE) {
						RIF(PAREXPECT(buf, ","));
						*buf += 1;
					}
				}
				else {
					RIF(PAREXPECT(buf, ","));
					*buf += 1;
				}
			}
			RIF(xk_parse(tbl, buf, &np[i*tbl->size], nptr ? -1 : 0,
                                     0, (void *)-1, tbl_find));
			i++;
			struct_size = i;
			xk_skipwhite(buf);
		}
		RIF(PAREXPECT(buf, Str_close_curly));
		*buf += 1;
		return(SUCCESS);
	}
	/*
	 * If there is no delimiter, and there are two levels of pointer,
	 * then we are a NULL terminated array of pointers
	 */
	if (tbl->delim == 0 &&
		((nptr == 2 && sub == 0) || (sub == 1 && nptr == 1))) {
		/*
		 * malloc a few members, realloc as needed
		 */
		nmal = MALMEMBERS;
		if ((((char **)p)[0] = malloc(nmal*tbl->size)) == NULL) {
			return(FAIL);
		}
		xk_skipwhite(buf);
		RIF(PAREXPECT(buf, Str_open_curly));
		*buf += 1;
		xk_skipwhite(buf);
		while (PARPEEK(buf, Str_close_curly) == FALSE) {
			if (i >= nmal) {
				nmal += MALMEMBERS;
				if ((((char **)p)[0] = realloc(((char **)p)[0], nmal*tbl->size)) == NULL) {
					return(FAIL);
				}
				if (_Prdebug) {
				   errmsg=strdup(GetSharedMsg(
                                               DT_XK_PARSE_ARRAY_OVERFLOW));
				   fprintf(stderr, errmsg, tbl->name, nmal, nmal*tbl->size);
                                   free(errmsg);
				}
			}
			if (_Prdebug)
                        {
			   errmsg=strdup(GETMESSAGE(8,8, 
                             "xk_parse: Parsing array element [%d] of '%s'\n"));
			   fprintf(stderr, errmsg, i, tbl->name);
                           free(errmsg);
                        }
			if (i) {
				RIF(PAREXPECT(buf, ","));
				*buf += 1;
			}
			RIF(xk_parse(tbl, buf, &p[i*tbl->size], 
                                     nptr == 2 ? -2 : -1, 0, (void *)-1, 
                                     tbl_find));

			xk_skipwhite(buf);
		}
		RIF(PAREXPECT(buf, Str_close_curly));
		*buf++;
		((char **)p)[i*tbl->size] = NULL;
		return(SUCCESS);
	}

	switch(tbl->kind) {
	case K_CHAR:
		RIF(xk_par_int(buf, &val, pass));
		((unsigned char *)p)[0] = val;
		break;
	case K_SHORT:
		RIF(xk_par_int(buf, &val, pass));
		((ushort *)p)[0] = val;
		break;
	case K_INT:
		RIF(xk_par_int(buf, &val, pass));
		((int *)p)[0] = val;
		break;
	case K_LONG:
		RIF(xk_par_int(buf, (long *)p, pass));
		break;
	case K_STRING:
		if (tbl->subscr) {
			val = tbl->subscr;
			RIF(xk_par_chararr(buf, (char *)p, (int *)&val));
			if (tbl->delim <= 0 && val > -1) {
				p[val] = '\0';
			}
		} else {
			val = 0;
			RIF(xk_par_charstr(buf, (char **)p, (int *)&val));
			/* If this is not a delimited char string,
			 * then it must be null terminated
			 */
			if (tbl->delim <= 0 && val > -1) {
				((char **) p)[0][val] = '\0';
			}
			strglen = val;
		}
		break;
	case K_TYPEDEF:
		ntbl = tbl_find(tbl->tname, tbl->tbl, tbl->id);
		RIF(xk_parse(ntbl, buf, p, nptr, 0, pass, tbl_find));
		return(SUCCESS);
	case K_STRUCT:
		xk_skipwhite(buf);
		RIF(PAREXPECT(buf, Str_open_curly));
		*buf += 1;
		ntbl = tbl_find(tbl->tname, tbl->tbl, tbl->id);
		pp = NULL;
		for (i = 0; ntbl[i].name != NULL; i++) {
			_Delim = xk_get_pardelim(&ntbl[i], p);
			if (ntbl[i].kind >= K_DSHORT) {
				skind = ntbl[i].kind;
				pp = p + ntbl[i].offset;
				struct_size = 0;
			}
			if (ntbl[i].delim) {
				delim_type = ntbl[i].kind;
			}
			if (i && ntbl[i-1].kind < K_DSHORT) {
				xk_skipwhite(buf);
				if (PARPEEK(buf, ",") == FALSE) {
					if (PARPEEK(buf, Str_close_curly) == FALSE) {
						RIF(PAREXPECT(buf, ","));
						*buf += 1;
					}
				}
				else  {
					RIF(PAREXPECT(buf, ","));
					*buf += 1;
				}
			}
			if (_Prdebug)
                        {
			   errmsg=strdup(GETMESSAGE(8,9, 
                              "xk_parse: Parsing member '%s' into location 0x%x\n"));
			   fprintf(stderr, errmsg, ntbl[i].name, p + ntbl[i].offset);
                           free(errmsg);
                        }
			if (xk_parse(&ntbl[i], buf, p+ntbl[i].offset, nptr, sub, pass, tbl_find) == FAIL) {
				if (_Prdebug)
                                {
				   errmsg=strdup(GetSharedMsg(
                                                    DT_XK_PARSE_ERROR));
				   fprintf(stderr, errmsg, ntbl[i].name);
                                   free(errmsg);
                                }
				return(FAIL);
			}
		}
		if (pp != NULL) {
			switch(skind) {
				case K_DSHORT:
					if (delim_type == K_STRING)
						((short *)pp)[0] = strglen;
					else
						((short *)pp)[0] = struct_size;
					break;
				case K_DINT:
					if (delim_type == K_STRING)
						((int *)pp)[0] = strglen;
					else
						((int *)pp)[0] = struct_size;
					break;
				case K_DLONG:
					if (delim_type == K_STRING)
						((long *)pp)[0] = strglen;
					else
						((long *)pp)[0] = struct_size;
					break;
				default:
					break;
			}
		}
		xk_skipwhite(buf);
		RIF(PAREXPECT(buf, Str_close_curly));
		*buf += 1;
		break;
	case K_UNION:
		if (strncmp(tbl[-1].name, "ch_", 3) != 0) {
			if (_Prdebug)
                        {
			   errmsg=strdup(GETMESSAGE(8,10, 
                            "xk_parse: Cannot determine the choice in '%s'\n"));
			   fprintf(stderr, errmsg, tbl->name);
                           free(errmsg);
                        }
			return(FAIL);
		}
		ntbl = tbl_find(tbl->tname, tbl->tbl, tbl->id);
		xk_skipwhite(buf);
		RIF(PAREXPECT(buf, Str_open_curly));
		*buf += 1;
		for (i = 0; ntbl[i].name != NULL; i++) {
			if (xk_parpeek(buf, ntbl[i].name) == TRUE) {
				RIF(xk_parexpect(buf, ntbl[i].name));
				((long *)(p - sizeof(long)))[0] = ntbl[i].choice;
				if (_Prdebug)
                                {
				   errmsg=strdup(GETMESSAGE(8,11, 
                                       "xk_parse: Parsing union member '%s' into location 0x%x\n"));
				   fprintf(stderr, errmsg, ntbl[i].name, p + ntbl[i].offset);
                                   free(errmsg);
                                }
				if (xk_parse(&ntbl[i], buf, p, nptr, sub, pass, tbl_find) == FAIL) {
				   if (_Prdebug)
                                   {
				      errmsg=strdup(GetSharedMsg(
                                                     DT_XK_PARSE_ERROR));
				      fprintf(stderr, errmsg, ntbl[i].name);
                                      free(errmsg);
                                   }
				   return(FAIL);
				}
				break;
			}
		}
		xk_skipwhite(buf);
		RIF(PAREXPECT(buf, Str_close_curly));
		*buf += 1;
		break;
	case K_DSHORT:
	case K_DINT:
	case K_DLONG:
		break;
	default:
		return(FAIL);
	}
	return(SUCCESS);
}