Esempio n. 1
0
/*
 * In-line data blocks are implemented as a here-document:
 * $FOO << EOD
 *  data line 1
 *  data line 2
 *  ...
 * EOD
 *
 * The data block name must begin with $ followed by a letter.
 * The string EOD is arbitrary; lines of data will be read from the input stream
 * until the leading characters on the line match the given character string.
 * No attempt is made to parse the data at the time it is read in.
 */
void
datablock_command()
{
    FILE *fin;
    char *name, *eod;
    int nlines;
    int nsize = 4;
    struct udvt_entry *datablock;
    char dataline[MAX_LINE_LEN+1];

    if (!isletter(c_token+1))
	int_error(c_token, "illegal datablock name");

    /* Create or recycle a datablock with the requested name */
    name = parse_datablock_name();
    datablock = add_udv_by_name(name);

    if (!datablock->udv_undef)
	gpfree_datablock(&datablock->udv_value);
    datablock->udv_undef = FALSE;
    datablock->udv_value.type = DATABLOCK;
    datablock->udv_value.v.data_array = NULL;

    if (!equals(c_token, "<<") || !isletter(c_token+1))
	int_error(c_token, "data block name must be followed by << EODmarker");
    c_token++;
    eod = gp_alloc(token[c_token].length +2, "datablock");
    copy_str(&eod[0], c_token, token[c_token].length + 2);
    c_token++;

    /* Read in and store data lines until EOD */
    fin = (lf_head == NULL) ? stdin : lf_head->fp;
    if (!fin)
	int_error(NO_CARET,"attempt to define data block from invalid context");
    for (nlines = 0; fgets(dataline, MAX_LINE_LEN, fin); nlines++) {
	int n;

	if (!strncmp(eod, dataline, strlen(eod)))
	    break;
	/* Allocate space for data lines plus at least 2 empty lines at the end. */
	if (nlines >= nsize-4) {
	    nsize *= 2;
	    datablock->udv_value.v.data_array =
		gp_realloc( datablock->udv_value.v.data_array,
			nsize * sizeof(char *), "datablock");
	    memset(&datablock->udv_value.v.data_array[nlines], 0,
		    (nsize - nlines) * sizeof(char *));
	}
	/* Strip trailing newline character */
	n = strlen(dataline);
	if (n > 0 && dataline[n - 1] == '\n')
	    dataline[n - 1] = NUL;
	datablock->udv_value.v.data_array[nlines] = gp_strdup(dataline);
    }
    inline_num += nlines + 1;	/* Update position in input file */

    free(eod);
    return;
}
Esempio n. 2
0
File: parse.c Progetto: Reen/gnuplot
/* Used by plot2d/plot3d/fit:
 * Parse an expression that may return a string or may return a constant or may
 * be a dummy function using dummy variables x, y, ...
 * If any dummy variables are present, set (*atptr) to point to an action table
 * corresponding to the parsed expression, and return NULL.
 * Otherwise evaluate the expression and return a string if there is one.
 * The return value "str" and "*atptr" both point to locally-managed memory,
 * which must not be freed by the caller!
 */
char*
string_or_express(struct at_type **atptr)
{
    int i;
    TBOOLEAN has_dummies;

    static char* str = NULL;
    free(str);
    str = NULL;

    if (atptr)
	*atptr = NULL;

    if (END_OF_COMMAND)
	int_error(c_token, "expression expected");

    /* parsing for datablocks */
    if (equals(c_token,"$"))
	return parse_datablock_name();

    if (isstring(c_token)) {
	str = try_to_get_string();
	return str;
    }

    /* parse expression */
    temp_at();

    /* check if any dummy variables are used */
    has_dummies = FALSE;
    for (i = 0; i < at->a_count; i++) {
	enum operators op_index = at->actions[i].index;
	if ( op_index == PUSHD1 || op_index == PUSHD2 || op_index == PUSHD
                || op_index == SUM ) {
	    has_dummies = TRUE;
	    break;
	}
    }

    if (!has_dummies) {
	/* no dummy variables: evaluate expression */
	struct value val;

	evaluate_at(at, &val);
	if (!undefined && val.type == STRING)
	    str = val.v.string_val;
    }

    /* prepare return */
    if (atptr)
	*atptr  = at;
    return str;
}