Example #1
0
long
parse_color_name()
{
    char *string;
    long color = -2;

    /* Terminal drivers call this after seeing a "background" option */
    if (almost_equals(c_token,"rgb$color") && almost_equals(c_token-1,"back$ground"))
	c_token++;
    if ((string = try_to_get_string())) {
	int iret;
	iret = lookup_table_nth(pm3d_color_names_tbl, string);
	if (iret >= 0)
	    color = pm3d_color_names_tbl[iret].value;
	else if (string[0] == '#')
	    iret = sscanf(string,"#%lx",&color);
	else if (string[0] == '0' && (string[1] == 'x' || string[1] == 'X'))
	    iret = sscanf(string,"%lx",&color);
	free(string);
	if (color == -2)
	    int_error(c_token, "unrecognized color name and not a string \"#AARRGGBB\" or \"0xAARRGGBB\"");
    } else {
	color = int_expression();
    }

    return (unsigned int)(color);
}
Example #2
0
/* Look for an iterate-over-plot construct, of the form
 *    {s}plot  for [<var> = <start> : <end> { : <increment>}] ...
 */
void
check_for_iteration()
{
    char *errormsg = "Expecting iterator \tfor [<var> = <start> : <end>]\n\t\t\tor\tfor [<var> in \"string of words\"]";

    iteration_udv = NULL;
    free(iteration_string);
    iteration_string = NULL;
    iteration_increment = 1;
    iteration = 0;

    if (!equals(c_token, "for"))
	return;

    c_token++;
    if (!equals(c_token++, "[") || !isletter(c_token))
	int_error(c_token-1, errormsg);
    iteration_udv = add_udv(c_token++);

    if (equals(c_token, "=")) {
	c_token++;
	iteration_start = int_expression();
	if (!equals(c_token++, ":"))
	    int_error(c_token-1, errormsg);
	iteration_end = int_expression();
	if (equals(c_token,":")) {
	    c_token++;
	    iteration_increment = int_expression();
	}
	if (!equals(c_token++, "]"))
	    int_error(c_token-1, errormsg);
	if (iteration_udv->udv_undef == FALSE)
	    gpfree_string(&iteration_udv->udv_value);
	Ginteger(&(iteration_udv->udv_value), iteration_start);
	iteration_udv->udv_undef = FALSE;
    }

    else if (equals(c_token++, "in")) {
	iteration_string = try_to_get_string();
	if (!iteration_string)
	    int_error(c_token-1, errormsg);
	if (!equals(c_token++, "]"))
	    int_error(c_token-1, errormsg);
	iteration_start = 1;
	iteration_end = gp_words(iteration_string);
	if (iteration_udv->udv_undef == FALSE)
	    gpfree_string(&iteration_udv->udv_value);
	Gstring(&(iteration_udv->udv_value), gp_word(iteration_string, 1));
	iteration_udv->udv_undef = FALSE;
    }

    else /* Neither [i=B:E] or [s in "foo"] */
 	int_error(c_token-1, errormsg);

    iteration_current = iteration_start;

}
Example #3
0
File: parse.c Project: 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;
}
Example #4
0
long
parse_color_name()
{
    char *string;
    long color = -1;

    if (almost_equals(c_token,"rgb$color"))
	c_token++;
    if ((string = try_to_get_string())) {
	color = lookup_table_nth(pm3d_color_names_tbl, string);
	if (color >= 0)
	    color = pm3d_color_names_tbl[color].value;
	else
	    sscanf(string,"#%lx",&color);
	free(string);
    }

    if (color == -1)
	int_error(c_token, "not recognized as a color name or a string of form \"#RRGGBB\"");

    return (unsigned int)(color);
}
Example #5
0
File: parse.c Project: Reen/gnuplot
/* Look for iterate-over-plot constructs, of the form
 *    for [<var> = <start> : <end> { : <increment>}] ...
 * If one (or more) is found, an iterator structure is allocated and filled
 * and a pointer to that structure is returned.
 * The pointer is NULL if no "for" statements are found.
 */
t_iterator *
check_for_iteration()
{
    char *errormsg = "Expecting iterator \tfor [<var> = <start> : <end> {: <incr>}]\n\t\t\tor\tfor [<var> in \"string of words\"]";
    int nesting_depth = 0;
    t_iterator *iter = NULL;
    t_iterator *this_iter = NULL;

    /* Now checking for iteration parameters */
    /* Nested "for" statements are supported, each one corresponds to a node of the linked list */
    while (equals(c_token, "for")) {
	struct udvt_entry *iteration_udv = NULL;
	char *iteration_string = NULL;
	int iteration_start;
	int iteration_end;
	int iteration_increment = 1;
	int iteration_current;
	int iteration = 0;
	TBOOLEAN empty_iteration;
	TBOOLEAN just_once = FALSE;

	c_token++;
	if (!equals(c_token++, "[") || !isletter(c_token))
	    int_error(c_token-1, errormsg);
	iteration_udv = add_udv(c_token++);

	if (equals(c_token, "=")) {
	    c_token++;
	    iteration_start = int_expression();
	    if (!equals(c_token++, ":"))
	    	int_error(c_token-1, errormsg);
	    iteration_end = int_expression();
	    if (equals(c_token,":")) {
	    	c_token++;
	    	iteration_increment = int_expression();
		if (iteration_increment == 0)
		    int_error(c_token-1, errormsg);
	    }
	    if (!equals(c_token++, "]"))
	    	int_error(c_token-1, errormsg);
	    if (iteration_udv->udv_undef == FALSE)
		gpfree_string(&(iteration_udv->udv_value));
	    Ginteger(&(iteration_udv->udv_value), iteration_start);
	    iteration_udv->udv_undef = FALSE;
	}
	else if (equals(c_token++, "in")) {
	    iteration_string = try_to_get_string();
	    if (!iteration_string)
	    	int_error(c_token-1, errormsg);
	    if (!equals(c_token++, "]"))
	    	int_error(c_token-1, errormsg);
	    iteration_start = 1;
	    iteration_end = gp_words(iteration_string);
	    if (iteration_udv->udv_undef == FALSE)
	    	gpfree_string(&(iteration_udv->udv_value));
	    Gstring(&(iteration_udv->udv_value), gp_word(iteration_string, 1));
	    iteration_udv->udv_undef = FALSE;
	}
	else /* Neither [i=B:E] or [s in "foo"] */
	    int_error(c_token-1, errormsg);

	iteration_current = iteration_start;

	empty_iteration = FALSE;	
	if ( (iteration_udv != NULL)
	&&   ((iteration_end > iteration_start && iteration_increment < 0)
	   || (iteration_end < iteration_start && iteration_increment > 0))) {
		empty_iteration = TRUE;
		FPRINTF((stderr,"Empty iteration\n"));
	}

	/* Allocating a node of the linked list nested iterations. */
	/* Iterating just once is the same as not iterating at all */
	/* so we skip building the node in that case.		   */
	if (iteration_start == iteration_end)
	    just_once = TRUE;
	if (iteration_start < iteration_end && iteration_end < iteration_start + iteration_increment)
	    just_once = TRUE;
	if (iteration_start > iteration_end && iteration_end > iteration_start + iteration_increment)
	    just_once = TRUE;

	if (!just_once) {
	    this_iter = gp_alloc(sizeof(t_iterator), "iteration linked list");
	    this_iter->iteration_udv = iteration_udv; 
	    this_iter->iteration_string = iteration_string;
	    this_iter->iteration_start = iteration_start;
	    this_iter->iteration_end = iteration_end;
	    this_iter->iteration_increment = iteration_increment;
	    this_iter->iteration_current = iteration_current;
	    this_iter->iteration = iteration;
	    this_iter->done = FALSE;
	    this_iter->really_done = FALSE;
	    this_iter->empty_iteration = empty_iteration;
	    this_iter->next = NULL;
	    this_iter->prev = NULL;
	    if (nesting_depth == 0) {
		/* first "for" statement: this will be the listhead */
		iter = this_iter;
	    }
	    else {
		/* not the first "for" statement: attach the newly created node to the end of the list */
		iter->prev->next = this_iter;  /* iter->prev points to the last node of the list */
		this_iter->prev = iter->prev;
	    }
	    iter->prev = this_iter; /* a shortcut: making the list circular */

	    /* if one iteration in the chain is empty, the subchain of nested iterations is too */
	    if (!iter->empty_iteration) 
		iter->empty_iteration = empty_iteration;

	    nesting_depth++;
	}
    }

    return iter;
}
Example #6
0
void
multiplot_start()
{
    TBOOLEAN set_spacing = FALSE;
    TBOOLEAN set_margins = FALSE;

    c_token++;

    /* Only a few options are possible if we are already in multiplot mode */
    /* So far we have "next".  Maybe also "previous", "clear"? */
    if (multiplot) {
	if (equals(c_token, "next")) {
	    c_token++;
	    if (!mp_layout.auto_layout)
		int_error(c_token, "only valid inside an auto-layout multiplot");
	    multiplot_next();
	    return;
	} else if (almost_equals(c_token, "prev$ious")) {
	    c_token++;
	    if (!mp_layout.auto_layout)
		int_error(c_token, "only valid inside an auto-layout multiplot");
	    multiplot_previous();
	    return;
	} else {
	    term_end_multiplot();
	}
    }

    /* FIXME: more options should be reset/initialized each time */
    mp_layout.auto_layout = FALSE;
    mp_layout.auto_layout_margins = FALSE;
    mp_layout.current_panel = 0;
    mp_layout.title.noenhanced = FALSE;
    free(mp_layout.title.text);
    mp_layout.title.text = NULL;
    free(mp_layout.title.font);
    mp_layout.title.font = NULL;

    /* Parse options */
    while (!END_OF_COMMAND) {

	if (almost_equals(c_token, "ti$tle")) {
	    c_token++;
	    mp_layout.title.text = try_to_get_string();
 	    continue;
       }

       if (equals(c_token, "font")) {
	    c_token++;
	    mp_layout.title.font = try_to_get_string();
	    continue;
	}

        if (almost_equals(c_token,"enh$anced")) {
            mp_layout.title.noenhanced = FALSE;
            c_token++;
            continue;
        }

        if (almost_equals(c_token,"noenh$anced")) {
            mp_layout.title.noenhanced = TRUE;
            c_token++;
            continue;
        }

	if (almost_equals(c_token, "lay$out")) {
	    if (mp_layout.auto_layout)
		int_error(c_token, "too many layout commands");
	    else
		mp_layout.auto_layout = TRUE;

	    c_token++;
	    if (END_OF_COMMAND) {
		int_error(c_token,"expecting '<num_cols>,<num_rows>'");
	    }

	    /* read row,col */
	    mp_layout.num_rows = int_expression();
	    if (END_OF_COMMAND || !equals(c_token,",") )
		int_error(c_token, "expecting ', <num_cols>'");

	    c_token++;
	    if (END_OF_COMMAND)
		int_error(c_token, "expecting <num_cols>");
	    mp_layout.num_cols = int_expression();

	    /* remember current values of the plot size and the margins */
	    mp_layout.prev_xsize = xsize;
	    mp_layout.prev_ysize = ysize;
	    mp_layout.prev_xoffset = xoffset;
	    mp_layout.prev_yoffset = yoffset;
	    mp_layout.prev_lmargin = lmargin;
	    mp_layout.prev_rmargin = rmargin;
	    mp_layout.prev_bmargin = bmargin;
	    mp_layout.prev_tmargin = tmargin;

	    mp_layout.act_row = 0;
	    mp_layout.act_col = 0;

	    continue;
	}

	/* The remaining options are only valid for auto-layout mode */
	if (!mp_layout.auto_layout)
	    int_error(c_token, "only valid in the context of an auto-layout command");

	switch(lookup_table(&set_multiplot_tbl[0],c_token)) {
	    case S_MULTIPLOT_COLUMNSFIRST:
		mp_layout.row_major = TRUE;
		c_token++;
		break;
	    case S_MULTIPLOT_ROWSFIRST:
		mp_layout.row_major = FALSE;
		c_token++;
		break;
	    case S_MULTIPLOT_DOWNWARDS:
		mp_layout.downwards = TRUE;
		c_token++;
		break;
	    case S_MULTIPLOT_UPWARDS:
		mp_layout.downwards = FALSE;
		c_token++;
		break;
	    case S_MULTIPLOT_SCALE:
		c_token++;
		mp_layout.xscale = real_expression();
		mp_layout.yscale = mp_layout.xscale;
		if (!END_OF_COMMAND && equals(c_token,",") ) {
		    c_token++;
		    if (END_OF_COMMAND) {
			int_error(c_token, "expecting <yscale>");
		    }
		    mp_layout.yscale = real_expression();
		}
		break;
	    case S_MULTIPLOT_OFFSET:
		c_token++;
		mp_layout.xoffset = real_expression();
		mp_layout.yoffset = mp_layout.xoffset;
		if (!END_OF_COMMAND && equals(c_token,",") ) {
		    c_token++;
		    if (END_OF_COMMAND) {
			int_error(c_token, "expecting <yoffset>");
		    }
		    mp_layout.yoffset = real_expression();
		}
		break;
	    case S_MULTIPLOT_MARGINS:
		c_token++;
		if (END_OF_COMMAND)
		    int_error(c_token,"expecting '<left>,<right>,<bottom>,<top>'");
		
		mp_layout.lmargin.scalex = screen;
		mp_layout_set_margin_or_spacing(&(mp_layout.lmargin));
		if (!END_OF_COMMAND && equals(c_token,",") ) {
		    c_token++;
		    if (END_OF_COMMAND)
			int_error(c_token, "expecting <right>");

		    mp_layout.rmargin.scalex = mp_layout.lmargin.scalex;
		    mp_layout_set_margin_or_spacing(&(mp_layout.rmargin));
		} else {
		    int_error(c_token, "expecting <right>");
		}
		if (!END_OF_COMMAND && equals(c_token,",") ) {
		    c_token++;
		    if (END_OF_COMMAND)
			int_error(c_token, "expecting <top>");

		    mp_layout.bmargin.scalex = mp_layout.rmargin.scalex;
		    mp_layout_set_margin_or_spacing(&(mp_layout.bmargin));
		} else {
		    int_error(c_token, "expecting <bottom>");
		}
		if (!END_OF_COMMAND && equals(c_token,",") ) {
		    c_token++;
		    if (END_OF_COMMAND)
			int_error(c_token, "expecting <bottom>");

		    mp_layout.tmargin.scalex = mp_layout.bmargin.scalex;
		    mp_layout_set_margin_or_spacing(&(mp_layout.tmargin));
		} else {
		    int_error(c_token, "expection <top>");
		}
		set_margins = TRUE;
		break;
	    case S_MULTIPLOT_SPACING:
		c_token++;
		if (END_OF_COMMAND)
		    int_error(c_token,"expecting '<xspacing>,<yspacing>'");
		mp_layout.xspacing.scalex = screen;
		mp_layout_set_margin_or_spacing(&(mp_layout.xspacing));
		mp_layout.yspacing = mp_layout.xspacing;

		if (!END_OF_COMMAND && equals(c_token, ",")) {
		    c_token++;
		    if (END_OF_COMMAND)
			int_error(c_token, "expecting <yspacing>");
		    mp_layout_set_margin_or_spacing(&(mp_layout.yspacing));
		}
		set_spacing = TRUE;
		break;
	    default:
		int_error(c_token,"invalid or duplicate option");
		break;
	}
    }

    if (set_spacing || set_margins) {
	if (set_spacing && set_margins) {
	    if (mp_layout.lmargin.x >= 0 && mp_layout.rmargin.x >= 0 
	    &&  mp_layout.tmargin.x >= 0 && mp_layout.bmargin.x >= 0 
	    &&  mp_layout.xspacing.x >= 0 && mp_layout.yspacing.x >= 0)
		mp_layout.auto_layout_margins = TRUE;
	    else
		int_error(NO_CARET, "must give positive margin and spacing values");
	} else if (set_spacing) {
	    int_warn(NO_CARET, "must give margins and spacing, continue with auto margins.");
	} else if (set_margins) {
	    mp_layout.auto_layout_margins = TRUE;
	    mp_layout.xspacing.scalex = screen;
	    mp_layout.xspacing.x = 0.05;
	    mp_layout.yspacing.scalex = screen;
	    mp_layout.yspacing.x = 0.05;
	    int_warn(NO_CARET, "must give margins and spacing, continue with spacing of 0.05");
	}
	/* Sanity check that screen tmargin is > screen bmargin */
	if (mp_layout.bmargin.scalex == screen && mp_layout.tmargin.scalex == screen)
	    if (mp_layout.bmargin.x > mp_layout.tmargin.x) {
		double tmp = mp_layout.bmargin.x;
		mp_layout.bmargin.x = mp_layout.tmargin.x;
		mp_layout.tmargin.x = tmp;
	    }
    }

    /* If we reach here, then the command has been successfully parsed.
     * Aug 2013: call term_start_plot() before setting multiplot so that
     * the wxt and qt terminals will reset the plot count to 0 before
     * ignoring subsequent TERM_LAYER_RESET requests. 
     */
    term_start_plot();
    multiplot = TRUE;
    fill_gpval_integer("GPVAL_MULTIPLOT", 1);

    /* Place overall title before doing anything else */
    if (mp_layout.title.text) {
	double tmpx, tmpy;
	unsigned int x, y;
	char *p = mp_layout.title.text;

	map_position_r(&(mp_layout.title.offset), &tmpx, &tmpy, "mp title");
	x = term->xmax  / 2 + tmpx;
	y = term->ymax - term->v_char + tmpy;;

	ignore_enhanced(mp_layout.title.noenhanced);
	apply_pm3dcolor(&(mp_layout.title.textcolor));
	write_multiline(x, y, mp_layout.title.text,
			CENTRE, JUST_TOP, 0, mp_layout.title.font);
	reset_textcolor(&(mp_layout.title.textcolor));
	ignore_enhanced(FALSE);

	/* Calculate fractional height of title compared to entire page */
	/* If it would fill the whole page, forget it! */
	for (y=1; *p; p++)
	    if (*p == '\n')
		y++;

	/* Oct 2012 - v_char depends on the font used */
	if (mp_layout.title.font && *mp_layout.title.font)
	    term->set_font(mp_layout.title.font);
	mp_layout.title_height = (double)(y * term->v_char) / (double)term->ymax;
	if (mp_layout.title.font && *mp_layout.title.font)
	    term->set_font("");

	if (mp_layout.title_height > 0.9)
	    mp_layout.title_height = 0.05;
    } else {
	mp_layout.title_height = 0.0;
    }

    if (mp_layout.auto_layout_margins)
	mp_layout_margins_and_spacing();
    else
	mp_layout_size_and_offset();
}
Example #7
0
// Called when terminal type is selected.
// This procedure should parse options on the command line.
// A list of the currently selected options should be stored in term_options[],
// in a form suitable for use with the set term command.
// term_options[] is used by the save command.  Use options_null() if no options are available." *
void qt_options()
{
	char *s = NULL;
	QString fontSettings;
	bool duplication = false;
	bool set_enhanced = false, set_font = false;
	bool set_persist = false, set_number = false;
	bool set_raise = false, set_ctrl = false;
	bool set_title = false, set_close = false;
	bool set_size = false;
	bool set_widget = false;
	bool set_dash = false;

	if (term_interlock != NULL && term_interlock != (void *)qt_init) {
		term = NULL;
		int_error(NO_CARET, "The qt terminal cannot be used in a wxt session");
	}

#define SETCHECKDUP(x) { c_token++; if (x) duplication = true; x = true; }

	while (!END_OF_COMMAND)
	{
		FPRINTF((stderr, "processing token\n"));
		switch (lookup_table(&qt_opts[0], c_token)) {
		case QT_WIDGET:
			SETCHECKDUP(set_widget);
			if (!(s = try_to_get_string()))
				int_error(c_token, "widget: expecting string");
			if (*s)
				qt_optionWidget = QString(s);
			free(s);
			break;
		case QT_FONT:
			SETCHECKDUP(set_font);
			if (!(s = try_to_get_string()))
				int_error(c_token, "font: expecting string");
			if (*s)
			{
				fontSettings = QString(s);
				QStringList list = fontSettings.split(',');
				if ((list.size() > 0) && !list[0].isEmpty())
					qt_optionFontName = list[0];
				if ((list.size() > 1) && (list[1].toInt() > 0))
					qt_optionFontSize = list[1].toInt();
			}
			free(s);
			break;
		case QT_ENHANCED:
			SETCHECKDUP(set_enhanced);
			qt_optionEnhanced = true;
			term->flags |= TERM_ENHANCED_TEXT;
			break;
		case QT_NOENHANCED:
			SETCHECKDUP(set_enhanced);
			qt_optionEnhanced = false;
			term->flags &= ~TERM_ENHANCED_TEXT;
			break;
		case QT_SIZE:
			SETCHECKDUP(set_size);
			if (END_OF_COMMAND)
				int_error(c_token, "size requires 'width,heigth'");
			qt_optionWidth = real_expression();
			if (!equals(c_token++, ","))
				int_error(c_token, "size requires 'width,heigth'");
			qt_optionHeight = real_expression();
			if (qt_optionWidth < 1 || qt_optionHeight < 1)
				int_error(c_token, "size is out of range");
			break;
		case QT_PERSIST:
			SETCHECKDUP(set_persist);
			qt_optionPersist = true;
			break;
		case QT_NOPERSIST:
			SETCHECKDUP(set_persist);
			qt_optionPersist = false;
			break;
		case QT_RAISE:
			SETCHECKDUP(set_raise);
			qt_optionRaise = true;
			break;
		case QT_NORAISE:
			SETCHECKDUP(set_raise);
			qt_optionRaise = false;
			break;
		case QT_CTRL:
			SETCHECKDUP(set_ctrl);
			qt_optionCtrl = true;
			break;
		case QT_NOCTRL:
			SETCHECKDUP(set_ctrl);
			qt_optionCtrl = false;
			break;
		case QT_TITLE:
			SETCHECKDUP(set_title);
			if (!(s = try_to_get_string()))
				int_error(c_token, "title: expecting string");
			if (*s)
				qt_optionTitle = qt_codec->toUnicode(s);
			free(s);
			break;
		case QT_CLOSE:
			SETCHECKDUP(set_close);
			break;
		case QT_DASH:
			SETCHECKDUP(set_dash);
			qt_optionDash = true;
			break;
		case QT_SOLID:
			SETCHECKDUP(set_dash);
			qt_optionDash = false;
			break;
		case QT_OTHER:
		default:
			qt_optionWindowId = int_expression();
			qt_optionWidget = "";
			if (set_number) duplication = true;
			set_number = true;
			break;
		}

		if (duplication)
			int_error(c_token-1, "Duplicated or contradicting arguments in qt term options.");
	}

	// Save options back into options string in normalized format
	QString termOptions = QString::number(qt_optionWindowId);

	/* Initialize user-visible font setting */
	fontSettings = qt_optionFontName + "," + QString::number(qt_optionFontSize);

	if (set_title)
	{
		termOptions += " title \"" + qt_optionTitle + '"';
		if (qt_initialized)
			qt_out << GETitle << qt_optionTitle;
	}

	if (set_size)
	{
		termOptions += " size " + QString::number(qt_optionWidth) + ", "
		                        + QString::number(qt_optionHeight);
		qt_setSize   = true;
		qt_setWidth  = qt_optionWidth;
		qt_setHeight = qt_optionHeight;
	}

	if (set_enhanced) termOptions +=  qt_optionEnhanced ? " enhanced" : " noenhanced";
	                  termOptions += " font \"" + fontSettings + '"';
	if (set_dash)     termOptions += qt_optionDash ? " dashed" : " solid";
	if (set_widget)   termOptions += " widget \"" + qt_optionWidget + '"';
	if (set_persist)  termOptions += qt_optionPersist ? " persist" : " nopersist";
	if (set_raise)    termOptions += qt_optionRaise ? " raise" : " noraise";
	if (set_ctrl)     termOptions += qt_optionCtrl ? " ctrl" : " noctrl";

	if (set_close && qt_initialized) qt_out << GECloseWindow << qt_optionWindowId;

	/// @bug change Utf8 to local encoding
	strncpy(term_options, termOptions.toUtf8().data(), MAX_LINE_LEN);
}
Example #8
0
/*
 * destination_class tells us whether we are filling in a line style ('set style line'),
 * a persistant linetype ('set linetype') or an ad hoc set of properties for a single
 * use ('plot ... lc foo lw baz').
 * allow_point controls whether we accept a point attribute in this lp_style.
 */
int
lp_parse(struct lp_style_type *lp, lp_class destination_class, TBOOLEAN allow_point)
{
    /* keep track of which options were set during this call */
    int set_lt = 0, set_pal = 0, set_lw = 0; 
    int set_pt = 0, set_ps  = 0, set_pi = 0;
    int set_dt = 0;
    int new_lt = 0;

    /* EAM Mar 2010 - We don't want properties from a user-defined default
     * linetype to override properties explicitly set here.  So fill in a
     * local lp_style_type as we go and then copy over the specifically
     * requested properties on top of the default ones.                                           
     */
    struct lp_style_type newlp = *lp;
	
    if ((destination_class == LP_ADHOC)
    && (almost_equals(c_token, "lines$tyle") || equals(c_token, "ls"))) {
	c_token++;
	lp_use_properties(lp, int_expression());
    } 
    
    while (!END_OF_COMMAND) {

	/* This special case is to flag an attemp to "set object N lt <lt>",
	 * which would otherwise be accepted but ignored, leading to confusion
	 * FIXME:  Couldn't this be handled at a higher level?
	 */
	if ((destination_class == LP_NOFILL)
	&&  (equals(c_token,"lt") || almost_equals(c_token,"linet$ype"))) {
	    int_error(c_token, "object linecolor must be set using fillstyle border");
	}

	if (almost_equals(c_token, "linet$ype") || equals(c_token, "lt")) {
	    if (set_lt++)
		break;
	    if (destination_class == LP_TYPE)
		int_error(c_token, "linetype definition cannot use linetype");
	    c_token++;
	    if (almost_equals(c_token, "rgb$color")) {
		if (set_pal++)
		    break;
		c_token--;
		parse_colorspec(&(newlp.pm3d_color), TC_RGB);
	    } else
		/* both syntaxes allowed: 'with lt pal' as well as 'with pal' */
		if (almost_equals(c_token, "pal$ette")) {
		    if (set_pal++)
			break;
		    c_token--;
		    parse_colorspec(&(newlp.pm3d_color), TC_Z);
		} else if (equals(c_token,"bgnd")) {
		    *lp = background_lp;
		    c_token++;
		} else if (equals(c_token,"black")) {
		    *lp = default_border_lp;
		    c_token++;
		} else if (equals(c_token,"nodraw")) {
		    lp->l_type = LT_NODRAW;
		    c_token++;
		} else {
		    /* These replace the base style */
		    new_lt = int_expression();
		    lp->l_type = new_lt - 1;
		    /* user may prefer explicit line styles */
		    if (prefer_line_styles && (destination_class != LP_STYLE))
			lp_use_properties(lp, new_lt);
		    else
			load_linetype(lp, new_lt);
		}
	} /* linetype, lt */

	/* both syntaxes allowed: 'with lt pal' as well as 'with pal' */
	if (almost_equals(c_token, "pal$ette")) {
	    if (set_pal++)
		break;
	    c_token--;
	    parse_colorspec(&(newlp.pm3d_color), TC_Z);
	    continue;
	}

	/* This is so that "set obj ... lw N fc <colorspec>" doesn't eat up the
	 * fc colorspec as a line property.  We need to parse it later as a
	 * _fill_ property. Also prevents "plot ... fc <col1> fs <foo> lw <baz>"
	 * from generating an error claiming redundant line properties.
	 */
	if ((destination_class == LP_NOFILL || destination_class == LP_ADHOC)
	&&  (equals(c_token,"fc") || almost_equals(c_token,"fillc$olor")))
	    break;

	if (equals(c_token,"lc") || almost_equals(c_token,"linec$olor")
	||  equals(c_token,"fc") || almost_equals(c_token,"fillc$olor")
	   ) {
	    if (set_pal++)
		break;
	    c_token++;
	    if (almost_equals(c_token, "rgb$color") || isstring(c_token)) {
		c_token--;
		parse_colorspec(&(newlp.pm3d_color), TC_RGB);
	    } else if (almost_equals(c_token, "pal$ette")) {
		c_token--;
		parse_colorspec(&(newlp.pm3d_color), TC_Z);
	    } else if (equals(c_token,"bgnd")) {
		newlp.pm3d_color.type = TC_LT;
		newlp.pm3d_color.lt = LT_BACKGROUND;
		c_token++;
	    } else if (equals(c_token,"black")) {
		newlp.pm3d_color.type = TC_LT;
		newlp.pm3d_color.lt = LT_BLACK;
		c_token++;
	    } else if (almost_equals(c_token, "var$iable")) {
		c_token++;
		newlp.l_type = LT_COLORFROMCOLUMN;
		newlp.pm3d_color.type = TC_LINESTYLE;
	    } else {
		/* Pull the line colour from a default linetype, but */
		/* only if we are not in the middle of defining one! */
		if (destination_class != LP_STYLE) {
		    struct lp_style_type temp;
		    load_linetype(&temp, int_expression());
		    newlp.pm3d_color = temp.pm3d_color;
		} else {
		    newlp.pm3d_color.type = TC_LT;
		    newlp.pm3d_color.lt = int_expression() - 1;
		}
	    }
	    continue;
	}

	if (almost_equals(c_token, "linew$idth") || equals(c_token, "lw")) {
	    if (set_lw++)
		break;
	    c_token++;
	    newlp.l_width = real_expression();
	    if (newlp.l_width < 0)
		newlp.l_width = 0;
	    continue;
	}

	if (equals(c_token,"bgnd")) {
	    if (set_lt++)
		break;;
	    c_token++;
	    *lp = background_lp;
	    continue;
	}

	if (equals(c_token,"black")) {
	    if (set_lt++)
		break;;
	    c_token++;
	    *lp = default_border_lp;
	    continue;
	}

	if (almost_equals(c_token, "pointt$ype") || equals(c_token, "pt")) {
	    if (allow_point) {
		char *symbol;
		if (set_pt++)
		    break;
		c_token++;
		if ((symbol = try_to_get_string())) {
		    newlp.p_type = PT_CHARACTER;
		    /* An alternative mechanism would be to use
		     * utf8toulong(&newlp.p_char, symbol);
		     */
		    strncpy((char *)(&newlp.p_char), symbol, 3);
		    /* Truncate ascii text to single character */
		    if ((((char *)&newlp.p_char)[0] & 0x80) == 0)
			((char *)&newlp.p_char)[1] = '\0';
		    /* UTF-8 characters may use up to 3 bytes */
		    ((char *)&newlp.p_char)[3] = '\0';
		    free(symbol);
		} else {
		    newlp.p_type = int_expression() - 1;
		}
	    } else {
		int_warn(c_token, "No pointtype specifier allowed, here");
		c_token += 2;
	    }
	    continue;
	}

	if (almost_equals(c_token, "points$ize") || equals(c_token, "ps")) {
	    if (allow_point) {
		if (set_ps++)
		    break;
		c_token++;
		if (almost_equals(c_token, "var$iable")) {
		    newlp.p_size = PTSZ_VARIABLE;
		    c_token++;
		} else if (almost_equals(c_token, "def$ault")) {
		    newlp.p_size = PTSZ_DEFAULT;
		    c_token++;
		} else {
		    newlp.p_size = real_expression();
		    if (newlp.p_size < 0)
			newlp.p_size = 0;
		}
	    } else {
		int_warn(c_token, "No pointsize specifier allowed, here");
		c_token += 2;
	    }
	    continue;
	}

	if (almost_equals(c_token, "pointi$nterval") || equals(c_token, "pi")) {
	    c_token++;
	    if (allow_point) {
		newlp.p_interval = int_expression();
		set_pi = 1;
	    } else {
		int_warn(c_token, "No pointinterval specifier allowed, here");
		int_expression();
	    }
	    continue;
	}

	if (almost_equals(c_token, "dasht$ype") || equals(c_token, "dt")) {
	    int tmp;
	    if (set_dt++)
		break;
	    c_token++;
	    tmp = parse_dashtype(&newlp.custom_dash_pattern);
	    /* Pull the dashtype from the list of already defined dashtypes, */
	    /* but only if it we didn't get an explicit one back from parse_dashtype */ 
	    if (tmp == DASHTYPE_AXIS)
		lp->l_type = LT_AXIS;
	    if (tmp >= 0)
		tmp = load_dashtype(&newlp.custom_dash_pattern, tmp + 1);
	    newlp.d_type = tmp;
	    continue;
	}


	/* caught unknown option -> quit the while(1) loop */
	break;
    }

    if (set_lt > 1 || set_pal > 1 || set_lw > 1 || set_pt > 1 || set_ps > 1 || set_dt > 1)
	int_error(c_token, "duplicated arguments in style specification");

    if (set_pal) {
	lp->pm3d_color = newlp.pm3d_color;
	/* hidden3d uses this to decide that a single color surface is wanted */
	lp->flags |= LP_EXPLICIT_COLOR;
    } else {
	lp->flags &= ~LP_EXPLICIT_COLOR;
    }
    if (set_lw)
	lp->l_width = newlp.l_width;
    if (set_pt) {
	lp->p_type = newlp.p_type;
	lp->p_char = newlp.p_char;
    }
    if (set_ps)
	lp->p_size = newlp.p_size;
    if (set_pi)
	lp->p_interval = newlp.p_interval;
    if (newlp.l_type == LT_COLORFROMCOLUMN)
	lp->l_type = LT_COLORFROMCOLUMN;
    if (set_dt) {
	lp->d_type = newlp.d_type;
	lp->custom_dash_pattern = newlp.custom_dash_pattern;
    }	
		

    return new_lt;
}
Example #9
0
int
parse_dashtype(struct t_dashtype *dt)
{
    int res = DASHTYPE_SOLID;
    int j = 0;
    int k = 0;
    char *dash_str = NULL;

    /* Erase any previous contents */
    memset(dt, 0, sizeof(struct t_dashtype));

    /* Fill in structure based on keyword ... */ 
    if (equals(c_token, "solid")) {
	res = DASHTYPE_SOLID;
	c_token++;

    /* Or numerical pattern consisting of pairs solid,empty,solid,empty... */
    } else if (equals(c_token, "(")) {
	c_token++;
	while (!END_OF_COMMAND) {
	    if (j >= DASHPATTERN_LENGTH) {
		int_error(c_token, "too many pattern elements");
	    }
	    dt->pattern[j++] = real_expression();	/* The solid portion */
	    if (!equals(c_token++, ","))
		int_error(c_token, "expecting comma");
	    dt->pattern[j++] = real_expression();	/* The empty portion */
	    if (equals(c_token, ")"))
		break;
	    if (!equals(c_token++, ","))
		int_error(c_token, "expecting comma");
	}

	if (!equals(c_token, ")"))
	    int_error(c_token, "expecting , or )");

	c_token++;
	res = DASHTYPE_CUSTOM;

    /* Or string representing pattern elements ... */
    } else if ((dash_str = try_to_get_string())) {
#define DSCALE 10.
	while (dash_str[j] && (k < DASHPATTERN_LENGTH || dash_str[j] == ' ')) {
	    /* .      Dot with short space 
	     * -      Dash with regular space
	     * _      Long dash with regular space
	     * space  Don't add new dash, just increase last space */
	    switch (dash_str[j]) {
	    case '.':
		dt->pattern[k++] = 0.2 * DSCALE;
		dt->pattern[k++] = 0.5 * DSCALE;
		break;
	    case '-':
		dt->pattern[k++] = 1.0 * DSCALE;
		dt->pattern[k++] = 1.0 * DSCALE;
		break;
	    case '_':
		dt->pattern[k++] = 2.0 * DSCALE;
		dt->pattern[k++] = 1.0 * DSCALE;
		break;
	    case ' ':
		if (k > 0)
		dt->pattern[k-1] += 1.0 * DSCALE;
		break;
	    default:
		int_error(c_token - 1, "expecting one of . - _ or space");
	    }
	    j++;
#undef  DSCALE
	}
	/* truncate dash_str if we ran out of space in the array representation */
	dash_str[j] = '\0';
	strncpy(dt->dstring, dash_str, sizeof(dt->dstring)-1);
	free(dash_str);
	res = DASHTYPE_CUSTOM;

    /* Or index of previously defined dashtype */
    /* FIXME: Is the index enough or should we copy its contents into this one? */
    /* FIXME: What happens if there is a recursive definition? */
    } else {
	res = int_expression();
	if (res < 0)
	    int_error(c_token - 1, "dashtype must be non-negative");
	if (res == 0)
	    res = DASHTYPE_AXIS;
	else
	    res = res - 1;
    }

    return res;
}
Example #10
0
static void
prepare_call(int calltype)
{
    struct udvt_entry *udv;
    int argindex;
    if (calltype == 2) {
	call_argc = 0;
	while (!END_OF_COMMAND && call_argc <= 9) {
	    call_args[call_argc] = try_to_get_string();
	    if (!call_args[call_argc]) {
		int save_token = c_token;

		/* This catches call "file" STRINGVAR (expression) */
		if (type_udv(c_token) == STRING) {
		    call_args[call_argc] = gp_strdup(add_udv(c_token)->udv_value.v.string_val);
		    c_token++;

		/* Evaluates a parenthesized expression and store the result in a string */
		} else if (equals(c_token, "(")) {
		    char val_as_string[32];
		    struct value a;
		    const_express(&a);
		    switch(a.type) {
			case CMPLX: /* FIXME: More precision? Some way to provide a format? */
				sprintf(val_as_string, "%g", a.v.cmplx_val.real);
				call_args[call_argc] = gp_strdup(val_as_string);
				break;
			default:
				int_error(save_token, "Unrecognized argument type");
				break;
			case INTGR:	
				sprintf(val_as_string, "%d", a.v.int_val);
				call_args[call_argc] = gp_strdup(val_as_string);
				break;
		    } 

		/* old (pre version 5) style wrapping of bare tokens as strings */
		/* is still useful for passing unquoted numbers */
		} else {
		    m_capture(&call_args[call_argc], c_token, c_token);
		    c_token++;
		}
	    }
	    call_argc++;
	}
	lf_head->c_token = c_token;
	if (!END_OF_COMMAND)
	    int_error(++c_token, "too many arguments for 'call <file>'");

    } else if (calltype == 5) {
	/* lf_push() moved our call arguments from call_args[] to lf->call_args[] */
	/* call_argc was determined at program entry */
	for (argindex = 0; argindex < 10; argindex++) {
	    call_args[argindex] = lf_head->call_args[argindex];
	    lf_head->call_args[argindex] = NULL;	/* just to be safe */
	}

    } else {
	/* "load" command has no arguments */
	call_argc = 0;
    }

    /* Old-style "call" arguments were referenced as $0 ... $9 and $# */
    /* New-style has ARG0 = script-name, ARG1 ... ARG9 and ARGC */
    /* FIXME:  If we defined these on entry, we could use get_udv* here */
    udv = add_udv_by_name("ARGC");
    Ginteger(&(udv->udv_value), call_argc);
    udv->udv_undef = FALSE;
    udv = add_udv_by_name("ARG0");
    gpfree_string(&(udv->udv_value));
    Gstring(&(udv->udv_value), gp_strdup(lf_head->name));
    udv->udv_undef = FALSE;
    for (argindex = 1; argindex <= 9; argindex++) {
	char *arg = gp_strdup(call_args[argindex-1]);
	udv = add_udv_by_name(argname[argindex]);
	gpfree_string(&(udv->udv_value));
	Gstring(&(udv->udv_value), arg ? arg : gp_strdup(""));
	udv->udv_undef = FALSE;
    }
}
Example #11
0
void 
statsrequest(void)
{ 
    int i;
    int columns;
    int columnsread;
    double v[2];
    static char *file_name = NULL;

    /* Vars to hold data and results */
    long n;                /* number of records retained */
    long max_n;

    static double *data_x = NULL;
    static double *data_y = NULL;   /* values read from file */
    long invalid;          /* number of missing/invalid records */
    long blanks;           /* number of blank lines */
    long doubleblanks;     /* number of repeated blank lines */
    long out_of_range;     /* number pts rejected, because out of range */

    struct file_stats res_file;
    struct sgl_column_stats res_x, res_y;
    struct two_column_stats res_xy;
    
    float *matrix;            /* matrix data. This must be float. */
    int nc, nr;               /* matrix dimensions. */
    int index;

    /* Vars for variable handling */
    static char *prefix = NULL;       /* prefix for user-defined vars names */

    /* Vars that control output */
    TBOOLEAN do_output = TRUE;     /* Generate formatted output */ 
    
    c_token++;

    /* Parse ranges */
    AXIS_INIT2D(FIRST_X_AXIS, 0);
    AXIS_INIT2D(FIRST_Y_AXIS, 0);
    parse_range(FIRST_X_AXIS);
    parse_range(FIRST_Y_AXIS);

    /* Initialize */
    columnsread = 2;
    invalid = 0;          /* number of missing/invalid records */
    blanks = 0;           /* number of blank lines */
    doubleblanks = 0;     /* number of repeated blank lines */
    out_of_range = 0;     /* number pts rejected, because out of range */
    n = 0;                /* number of records retained */
    nr = 0;               /* Matrix dimensions */
    nc = 0;
    max_n = INITIAL_DATA_SIZE;
    
    free(data_x);
    free(data_y);
    data_x = vec(max_n);       /* start with max. value */
    data_y = vec(max_n);

    if ( !data_x || !data_y )
      int_error( NO_CARET, "Internal error: out of memory in stats" );

    n = invalid = blanks = doubleblanks = out_of_range = nr = 0;

    /* Get filename */
    free ( file_name );
    file_name = try_to_get_string();

    if ( !file_name )
	int_error(c_token, "missing filename");

    /* ===========================================================
    v923z: insertion for treating matrices 
      EAM: only handles ascii matrix with uniform grid,
           and fails to apply any input data transforms
      =========================================================== */
    if ( almost_equals(c_token, "mat$rix") ) {
	df_open(file_name, 3, NULL);
	index = df_num_bin_records - 1;
	
	/* We take these values as set by df_determine_matrix_info
	See line 1996 in datafile.c */
	nc = df_bin_record[index].scan_dim[0];
	nr = df_bin_record[index].scan_dim[1];
	n = nc * nr;
	
	matrix = (float *)df_bin_record[index].memory_data;
	
	/* Fill up a vector, so that we can use the existing code. */
	if ( !redim_vec(&data_x, n ) ) {
	    int_error( NO_CARET, 
		   "Out of memory in stats: too many datapoints (%d)?", n );
	}
	for( i=0; i < n; i++ ) {
	    data_y[i] = (double)matrix[i];  
	}
	/* We can close the file here, there is nothing else to do */
	df_close();
	/* We will invoke single column statistics for the matrix */
	columns = 1;

    } else { /* Not a matrix */
	columns = df_open(file_name, 2, NULL); /* up to 2 using specs allowed */

	if (columns < 0)
	    int_error(NO_CARET, "Can't read data file"); 

	if (columns > 2 )
	    int_error(c_token, "Need 0 to 2 using specs for stats command");

	/* If the user has set an explicit locale for numeric input, apply it
	   here so that it affects data fields read from the input file. */
	/* v923z: where exactly should this be? here or before the matrix case? 
	 * I think, we should move everything here to before trying to open the file. 
	 * There is no point in trying to read anything, if the axis is logarithmic, e.g.
	 */
	set_numeric_locale();   

	/* For all these below: we could save the state, switch off, then restore */
	if ( axis_array[FIRST_X_AXIS].log || axis_array[FIRST_Y_AXIS].log )
	    int_error( NO_CARET, "Stats command not available with logscale active");

	if ( axis_array[FIRST_X_AXIS].datatype == DT_TIMEDATE || axis_array[FIRST_Y_AXIS].datatype == DT_TIMEDATE )
	    int_error( NO_CARET, "Stats command not available in timedata mode");

	if ( polar )
	    int_error( NO_CARET, "Stats command not available in polar mode" );

	if ( parametric )
	    int_error( NO_CARET, "Stats command not available in parametric mode" );

	/* The way readline and friends work is as follows:
	 - df_open will return the number of columns requested in the using spec
	   so that "columns" will be 0, 1, or 2 (no using, using 1, using 1:2)
	 - readline always returns the same number of columns (for us: 1 or 2)
	 - using 1:2 = return two columns, skipping lines w/ bad data
	 - using 1   = return sgl column (supply zeros (0) for the second col)
	 - no using  = return two columns (first two), fail on bad data 

	 We need to know how many columns to process. If columns==1 or ==2
	 (that is, if there was a using spec), all is clear and we use the
	 value of columns. 
	 But: if columns is 0, then we need to figure out the number of cols
	 read from the return value of readline. If readline ever returns
	 1, we take that; only if it always returns 2 do we assume two cols.
	 */
  
	while( (i = df_readline(v, 2)) != DF_EOF ) {
	    columnsread = ( i > columnsread ? i : columnsread );

	    if ( n >= max_n ) {
		max_n = (max_n * 3) / 2; /* increase max_n by factor of 1.5 */
	  
		/* Some of the reallocations went bad: */
		if ( 0 || !redim_vec(&data_x, max_n) || !redim_vec(&data_y, max_n) ) {
		    df_close();
		    int_error( NO_CARET, 
		       "Out of memory in stats: too many datapoints (%d)?",
		       max_n );
		} 
	    } /* if (need to extend storage space) */

	    switch (i) {
	    case DF_MISSING:
	    case DF_UNDEFINED:
	      /* Invalids are only recognized if the syntax is like this:
		     stats "file" using ($1):($2)
		 If the syntax is simply:
		     stats "file" using 1:2
		 then df_readline simply skips invalid records (does not
		 return anything!) Status: 2009-11-02 */
	      invalid += 1;
	      continue;
	      
	    case DF_FIRST_BLANK: 
	      blanks += 1;
	      continue;

	    case DF_SECOND_BLANK:      
	      blanks += 1;
	      doubleblanks += 1;
	      continue;
	      
	    case 0:
	      int_error( NO_CARET, "bad data on line %d of file %s",
	  		df_line_number, df_filename ? df_filename : "" );
	      break;

	    case 1: /* Read single column successfully  */
	      if ( validate_data(v[0], FIRST_Y_AXIS) )  {
		data_y[n] = v[0];
		n++;
	      } else {
		out_of_range++;
	      }
	      break;

	    case 2: /* Read two columns successfully  */
	      if ( validate_data(v[0], FIRST_X_AXIS) &&
		  validate_data(v[1], FIRST_Y_AXIS) ) {
		data_x[n] = v[0];
		data_y[n] = v[1];
		n++;
	      } else {
		out_of_range++;
	      }
	      break;
	    }
	} /* end-while : done reading file */
	df_close();

	/* now resize fields to actual length: */
	redim_vec(&data_x, n);
	redim_vec(&data_y, n);

	/* figure out how many columns where really read... */
	if ( columns == 0 )
	    columns = columnsread;

    }  /* end of case when the data file is not a matrix */

    /* Now finished reading user input; return to C locale for internal use*/
    reset_numeric_locale();

    /* PKJ - TODO: similar for logscale, polar/parametric, timedata */

    /* No data! Try to explain why. */
    if ( n == 0 ) {
	if ( out_of_range > 0 )
	    int_error( NO_CARET, "All points out of range" );
	else 
	    int_error( NO_CARET, "No valid data points found in file" );
    }

    /* Parse the remainder of the command line: 0 to 2 tokens possible */
    while( !(END_OF_COMMAND) ) {
	if ( almost_equals( c_token, "out$put" ) ) {
		do_output = TRUE;
		c_token++;

	} else if ( almost_equals( c_token, "noout$put" ) ) {
		do_output = FALSE;
		c_token++;

	} else if ( almost_equals(c_token, "pre$fix") 
	       ||   equals(c_token, "name")) {
	    c_token++;
	    free ( prefix );
	    prefix = try_to_get_string();
	    if (!legal_identifier(prefix) || !strcmp ("GPVAL_", prefix))
		int_error( --c_token, "illegal prefix" );

	}  else {
	    int_error( c_token, "Expecting [no]output or prefix");
	}

    }

    /* Set defaults if not explicitly set by user */
    if (!prefix)
	prefix = gp_strdup("STATS_");
    i = strlen(prefix);
    if (prefix[i-1] != '_') {
	prefix = gp_realloc(prefix, i+2, "prefix");
	strcat(prefix,"_");
    }

    /* Do the actual analysis */
    res_file = analyze_file( n, out_of_range, invalid, blanks, doubleblanks );
    if ( columns == 1 ) {
	res_y = analyze_sgl_column( data_y, n, nr );
    }

    if ( columns == 2 ) {
	/* If there are two columns, then the data file is not a matrix */
	res_x = analyze_sgl_column( data_x, n, 0 );
	res_y = analyze_sgl_column( data_y, n, 0 );
	res_xy = analyze_two_columns( data_x, data_y, res_x, res_y, n );
    }

    /* Store results in user-accessible variables */
    /* Clear out any previous use of these variables */
    del_udv_by_name( prefix, TRUE );

    file_variables( res_file, prefix );

    if ( columns == 1 ) {
	sgl_column_variables( res_y, prefix, "" );
    }
    
    if ( columns == 2 ) {
	sgl_column_variables( res_x, prefix, "_x" );
	sgl_column_variables( res_y, prefix, "_y" );
	two_column_variables( res_xy, prefix );
    }

    /* Output */
    if ( do_output ) {
	file_output( res_file );
	if ( columns == 1 )
	    sgl_column_output( res_y, res_file.records );
	else
	    two_column_output( res_x, res_y, res_xy, res_file.records );
    }

    /* Cleanup */
      
    free(data_x);
    free(data_y);

    data_x = NULL;
    data_y = NULL;
    
    free( file_name );
    file_name = NULL;
    
    free( prefix );
    prefix = NULL;
}
Example #12
0
/*
 * Parse the sub-options of text color specification
 *   { def$ault | lt <linetype> | pal$ette { cb <val> | frac$tion <val> | z }
 * The ordering of alternatives shown in the line above is kept in the symbol definitions
 * TC_DEFAULT TC_LT TC_RGB TC_CB TC_FRAC TC_Z  (0 1 2 3 4 5)
 * and the "options" parameter to parse_colorspec limits legal input to the
 * corresponding point in the series. So TC_LT allows only default or linetype
 * coloring, while TC_Z allows all coloring options up to and including pal z
 */
void
parse_colorspec(struct t_colorspec *tc, int options)
{
    c_token++;
    if (END_OF_COMMAND)
	int_error(c_token, "expected colorspec");
    if (almost_equals(c_token,"def$ault")) {
	c_token++;
	tc->type = TC_DEFAULT;
#ifdef KEYWORD_BGND
    } else if (equals(c_token,"bgnd")) {
	c_token++;
	tc->type = TC_LT;
	tc->lt = LT_BACKGROUND;
#endif
    } else if (equals(c_token,"lt")) {
	c_token++;
	if (END_OF_COMMAND)
	    int_error(c_token, "expected linetype");
	tc->type = TC_LT;
	tc->lt = int_expression()-1;
	if (tc->lt < LT_BACKGROUND) {
	    tc->type = TC_DEFAULT;
	    int_warn(c_token,"illegal linetype");
	}
    } else if (options <= TC_LT) {
	tc->type = TC_DEFAULT;
	int_error(c_token, "only tc lt <n> possible here");
    } else if (equals(c_token,"ls") || almost_equals(c_token,"lines$tyle")) {
	c_token++;
	tc->type = TC_LINESTYLE;
	tc->lt = real_expression();
    } else if (almost_equals(c_token,"rgb$color")) {
	char *color;
	int rgbtriple;
	c_token++;
	tc->type = TC_RGB;
	if (almost_equals(c_token, "var$iable")) {
	    tc->value = -1.0;
	    c_token++;
	    return;
	} else
	    tc->value = 0.0;
	if (!(color = try_to_get_string()))
	    int_error(c_token, "expected a color name or a string of form \"#RRGGBB\"");
	if ((rgbtriple = lookup_table_nth(pm3d_color_names_tbl, color)) >= 0)
	    rgbtriple = pm3d_color_names_tbl[rgbtriple].value;
	else
	    sscanf(color,"#%x",&rgbtriple);
	free(color);
	if (rgbtriple < 0)
	    int_error(c_token, "expected a known color name or a string of form \"#RRGGBB\"");
	tc->type = TC_RGB;
	tc->lt = rgbtriple;
    } else if (almost_equals(c_token,"pal$ette")) {
	c_token++;
	if (equals(c_token,"z")) {
	    /* The actual z value is not yet known, fill it in later */
	    if (options >= TC_Z) {
		tc->type = TC_Z;
	    } else {
		tc->type = TC_DEFAULT;
		int_error(c_token, "palette z not possible here");
	    }
	    c_token++;
	} else if (equals(c_token,"cb")) {
	    tc->type = TC_CB;
	    c_token++;
	    if (END_OF_COMMAND)
		int_error(c_token, "expected cb value");
	    tc->value = real_expression();
	} else if (almost_equals(c_token,"frac$tion")) {
	    tc->type = TC_FRAC;
	    c_token++;
	    if (END_OF_COMMAND)
		int_error(c_token, "expected palette fraction");
	    tc->value = real_expression();
	    if (tc->value < 0. || tc->value > 1.0)
		int_error(c_token, "palette fraction out of range");
	} else {
	    /* END_OF_COMMAND or palette <blank> */
	    if (options >= TC_Z)
		tc->type = TC_Z;
	}
    } else {
	int_error(c_token, "colorspec option not recognized");
    }
}