/* 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; }
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); }
/* process 'unset arrow' command */ static void unset_arrow() { struct arrow_def *this_arrow; struct arrow_def *prev_arrow; int tag; if (END_OF_COMMAND) { /* delete all arrows */ while (first_arrow != NULL) delete_arrow((struct arrow_def *) NULL, first_arrow); } else { /* get tag */ tag = int_expression(); if (!END_OF_COMMAND) int_error(c_token, "extraneous arguments to unset arrow"); for (this_arrow = first_arrow, prev_arrow = NULL; this_arrow != NULL; prev_arrow = this_arrow, this_arrow = this_arrow->next) { if (this_arrow->tag == tag) { delete_arrow(prev_arrow, this_arrow); return; /* exit, our job is done */ } } } }
/******** The 'unset' command ********/ void unset_command() { int found_token; int save_token; int i; c_token++; set_iterator = check_for_iteration(); found_token = lookup_table(&set_tbl[0],c_token); /* HBB 20000506: rationalize occurences of c_token++ ... */ if (found_token != S_INVALID) c_token++; save_token = c_token; ITERATE: switch(found_token) { case S_ANGLES: unset_angles(); break; case S_ARROW: unset_arrow(); break; case S_AUTOSCALE: unset_autoscale(); break; case S_BARS: unset_bars(); break; case S_BORDER: unset_border(); break; case S_BOXWIDTH: unset_boxwidth(); break; case S_CLIP: unset_clip(); break; case S_CNTRPARAM: unset_cntrparam(); break; case S_CNTRLABEL: unset_cntrlabel(); break; case S_CLABEL: /* deprecated command */ clabel_onecolor = TRUE; break; case S_CONTOUR: unset_contour(); break; case S_DASHTYPE: unset_dashtype(); break; case S_DGRID3D: unset_dgrid3d(); break; case S_DUMMY: unset_dummy(); break; case S_ENCODING: unset_encoding(); break; case S_DECIMALSIGN: unset_decimalsign(); break; case S_FIT: unset_fit(); break; case S_FORMAT: c_token--; set_format(); break; case S_GRID: unset_grid(); break; case S_HIDDEN3D: unset_hidden3d(); break; case S_HISTORY: break; /* FIXME: reset to default values? */ case S_HISTORYSIZE: /* Deprecated */ unset_historysize(); break; case S_ISOSAMPLES: unset_isosamples(); break; case S_KEY: unset_key(); break; case S_LABEL: unset_label(); break; case S_LINETYPE: unset_linetype(); break; case S_LINK: c_token--; link_command(); break; case S_LOADPATH: unset_loadpath(); break; case S_LOCALE: unset_locale(); break; case S_LOGSCALE: unset_logscale(); break; case S_MACROS: /* Aug 2013 - macros are always enabled */ break; case S_MAPPING: unset_mapping(); break; case S_BMARGIN: unset_margin(&bmargin); break; case S_LMARGIN: unset_margin(&lmargin); break; case S_RMARGIN: unset_margin(&rmargin); break; case S_TMARGIN: unset_margin(&tmargin); break; case S_DATAFILE: if (almost_equals(c_token,"fort$ran")) { df_fortran_constants = FALSE; c_token++; break; } else if (almost_equals(c_token,"miss$ing")) { unset_missing(); c_token++; break; } else if (almost_equals(c_token,"sep$arators")) { free(df_separators); df_separators = NULL; c_token++; break; } else if (almost_equals(c_token,"com$mentschars")) { free(df_commentschars); df_commentschars = gp_strdup(DEFAULT_COMMENTS_CHARS); c_token++; break; } else if (almost_equals(c_token,"bin$ary")) { df_unset_datafile_binary(); c_token++; break; } else if (almost_equals(c_token,"nofpe_trap")) { df_nofpe_trap = FALSE; c_token++; break; } df_fortran_constants = FALSE; unset_missing(); free(df_separators); df_separators = NULL; free(df_commentschars); df_commentschars = gp_strdup(DEFAULT_COMMENTS_CHARS); df_unset_datafile_binary(); break; #ifdef USE_MOUSE case S_MOUSE: unset_mouse(); break; #endif case S_MULTIPLOT: term_end_multiplot(); break; case S_OFFSETS: unset_offsets(); break; case S_ORIGIN: unset_origin(); break; case SET_OUTPUT: unset_output(); break; case S_PARAMETRIC: unset_parametric(); break; case S_PM3D: unset_pm3d(); break; case S_PALETTE: unset_palette(); break; case S_COLORBOX: unset_colorbox(); break; case S_POINTINTERVALBOX: unset_pointintervalbox(); break; case S_POINTSIZE: unset_pointsize(); break; case S_POLAR: unset_polar(); break; case S_PRINT: unset_print(); break; case S_PSDIR: unset_psdir(); break; #ifdef EAM_OBJECTS case S_OBJECT: unset_object(); break; #endif case S_RTICS: unset_tics(POLAR_AXIS); break; case S_PAXIS: i = int_expression(); if (i <= 0 || i > MAX_PARALLEL_AXES) int_error(c_token, "expecting parallel axis number"); if (almost_equals(c_token, "tic$s")) { unset_tics(PARALLEL_AXES+i-1); c_token++; } break; case S_SAMPLES: unset_samples(); break; case S_SIZE: unset_size(); break; case S_STYLE: unset_style(); break; case S_SURFACE: unset_surface(); break; case S_TABLE: unset_table(); break; case S_TERMINAL: unset_terminal(); break; case S_TICS: unset_tics(ALL_AXES); break; case S_TICSCALE: int_warn(c_token, "Deprecated syntax - use 'set tics scale default'"); break; case S_TICSLEVEL: case S_XYPLANE: unset_ticslevel(); break; case S_TIMEFMT: unset_timefmt(); break; case S_TIMESTAMP: unset_timestamp(); break; case S_TITLE: unset_axislabel_or_title(&title); break; case S_VIEW: unset_view(); break; case S_ZERO: unset_zero(); break; /* FIXME - are the tics correct? */ case S_MXTICS: unset_minitics(FIRST_X_AXIS); break; case S_XTICS: unset_tics(FIRST_X_AXIS); break; case S_XDTICS: case S_XMTICS: unset_month_day_tics(FIRST_X_AXIS); break; case S_MYTICS: unset_minitics(FIRST_Y_AXIS); break; case S_YTICS: unset_tics(FIRST_Y_AXIS); break; case S_YDTICS: case S_YMTICS: unset_month_day_tics(FIRST_X_AXIS); break; case S_MX2TICS: unset_minitics(SECOND_X_AXIS); break; case S_X2TICS: unset_tics(SECOND_X_AXIS); break; case S_X2DTICS: case S_X2MTICS: unset_month_day_tics(FIRST_X_AXIS); break; case S_MY2TICS: unset_minitics(SECOND_Y_AXIS); break; case S_Y2TICS: unset_tics(SECOND_Y_AXIS); break; case S_Y2DTICS: case S_Y2MTICS: unset_month_day_tics(FIRST_X_AXIS); break; case S_MZTICS: unset_minitics(FIRST_Z_AXIS); break; case S_ZTICS: unset_tics(FIRST_Z_AXIS); break; case S_ZDTICS: case S_ZMTICS: unset_month_day_tics(FIRST_X_AXIS); break; case S_MCBTICS: unset_minitics(COLOR_AXIS); break; case S_CBTICS: unset_tics(COLOR_AXIS); break; case S_CBDTICS: case S_CBMTICS: unset_month_day_tics(FIRST_X_AXIS); break; case S_MRTICS: unset_minitics(POLAR_AXIS); break; case S_XDATA: unset_timedata(FIRST_X_AXIS); break; case S_YDATA: unset_timedata(FIRST_Y_AXIS); break; case S_ZDATA: unset_timedata(FIRST_Z_AXIS); break; case S_CBDATA: unset_timedata(COLOR_AXIS); break; case S_X2DATA: unset_timedata(SECOND_X_AXIS); break; case S_Y2DATA: unset_timedata(SECOND_Y_AXIS); break; case S_XLABEL: unset_axislabel(FIRST_X_AXIS); break; case S_YLABEL: unset_axislabel(FIRST_Y_AXIS); break; case S_ZLABEL: unset_axislabel(FIRST_Z_AXIS); break; case S_CBLABEL: unset_axislabel(COLOR_AXIS); break; case S_X2LABEL: unset_axislabel(SECOND_X_AXIS); break; case S_Y2LABEL: unset_axislabel(SECOND_Y_AXIS); break; case S_XRANGE: unset_range(FIRST_X_AXIS); break; case S_X2RANGE: unset_range(SECOND_X_AXIS); break; case S_YRANGE: unset_range(FIRST_Y_AXIS); break; case S_Y2RANGE: unset_range(SECOND_Y_AXIS); break; case S_ZRANGE: unset_range(FIRST_Z_AXIS); break; case S_CBRANGE: unset_range(COLOR_AXIS); break; case S_RRANGE: unset_range(POLAR_AXIS); break; case S_TRANGE: unset_range(T_AXIS); break; case S_URANGE: unset_range(U_AXIS); break; case S_VRANGE: unset_range(V_AXIS); break; case S_RAXIS: raxis = FALSE; c_token++; break; case S_XZEROAXIS: unset_zeroaxis(FIRST_X_AXIS); break; case S_YZEROAXIS: unset_zeroaxis(FIRST_Y_AXIS); break; case S_ZZEROAXIS: unset_zeroaxis(FIRST_Z_AXIS); break; case S_X2ZEROAXIS: unset_zeroaxis(SECOND_X_AXIS); break; case S_Y2ZEROAXIS: unset_zeroaxis(SECOND_Y_AXIS); break; case S_ZEROAXIS: unset_all_zeroaxes(); break; case S_INVALID: default: int_error(c_token, "Unrecognized option. See 'help unset'."); break; } if (next_iteration(set_iterator)) { c_token = save_token; goto ITERATE; } update_gpval_variables(0); set_iterator = cleanup_iteration(set_iterator); }
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(); }
/* <fillstyle> = {empty | solid {<density>} | pattern {<n>}} {noborder | border {<lt>}} */ void parse_fillstyle(struct fill_style_type *fs, int def_style, int def_density, int def_pattern, t_colorspec def_bordertype) { TBOOLEAN set_fill = FALSE; TBOOLEAN set_param = FALSE; TBOOLEAN transparent = FALSE; /* Set defaults */ fs->fillstyle = def_style; fs->filldensity = def_density; fs->fillpattern = def_pattern; fs->border_color = def_bordertype; if (END_OF_COMMAND) return; if (!equals(c_token, "fs") && !almost_equals(c_token, "fill$style")) return; c_token++; while (!END_OF_COMMAND) { if (almost_equals(c_token, "trans$parent")) { transparent = TRUE; c_token++; } if (almost_equals(c_token, "e$mpty")) { fs->fillstyle = FS_EMPTY; c_token++; } else if (almost_equals(c_token, "s$olid")) { fs->fillstyle = transparent ? FS_TRANSPARENT_SOLID : FS_SOLID; set_fill = TRUE; c_token++; } else if (almost_equals(c_token, "p$attern")) { fs->fillstyle = transparent ? FS_TRANSPARENT_PATTERN : FS_PATTERN; set_fill = TRUE; c_token++; } if (END_OF_COMMAND) continue; else if (almost_equals(c_token, "bo$rder")) { fs->border_color.type = TC_DEFAULT; c_token++; if (equals(c_token,"-") || isanumber(c_token)) { fs->border_color.type = TC_LT; fs->border_color.lt = int_expression() - 1; } else if (equals(c_token,"lc") || almost_equals(c_token,"linec$olor")) { parse_colorspec(&fs->border_color, TC_Z); } else if (equals(c_token,"rgb") || equals(c_token,"lt") || almost_equals(c_token,"linet$ype")) { c_token--; parse_colorspec(&fs->border_color, TC_Z); } continue; } else if (almost_equals(c_token, "nobo$rder")) { fs->border_color.type = TC_LT; fs->border_color.lt = LT_NODRAW; c_token++; continue; } /* We hit something unexpected */ if (!set_fill || set_param) break; if (!(isanumber(c_token) || type_udv(c_token) == INTGR || type_udv(c_token) == CMPLX)) break; if (fs->fillstyle == FS_SOLID || fs->fillstyle == FS_TRANSPARENT_SOLID) { /* user sets 0...1, but is stored as an integer 0..100 */ fs->filldensity = 100.0 * real_expression() + 0.5; if (fs->filldensity < 0) fs->filldensity = 0; if (fs->filldensity > 100) fs->filldensity = 100; set_param = TRUE; } else if (fs->fillstyle == FS_PATTERN || fs->fillstyle == FS_TRANSPARENT_PATTERN) { fs->fillpattern = int_expression(); if (fs->fillpattern < 0) fs->fillpattern = 0; set_param = TRUE; } } }
/* * allow_ls controls whether we are allowed to accept linestyle in * the current context [ie not when doing a set linestyle command] * allow_point is whether we accept a point command */ int lp_parse(struct lp_style_type *lp, TBOOLEAN allow_ls, TBOOLEAN allow_point) { /* keep track of which options were set during this call */ int set_lt = 0, set_pal = 0, set_lw = 0, set_pt = 0, set_ps = 0, set_pi = 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 (allow_ls && (almost_equals(c_token, "lines$tyle") || equals(c_token, "ls"))) { c_token++; lp_use_properties(lp, int_expression()); } while (!END_OF_COMMAND) { if (almost_equals(c_token, "linet$ype") || equals(c_token, "lt")) { if (set_lt++) break; c_token++; if (almost_equals(c_token, "rgb$color")) { if (set_pal++) break; c_token--; parse_colorspec(&(newlp.pm3d_color), TC_RGB); newlp.use_palette = 1; } 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); newlp.use_palette = 1; } else if (equals(c_token,"bgnd")) { *lp = background_lp; 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 && allow_ls) 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); newlp.use_palette = 1; continue; } if (equals(c_token,"lc") || almost_equals(c_token,"linec$olor") || equals(c_token,"fc") || almost_equals(c_token,"fillc$olor")) { newlp.use_palette = 1; if (set_pal++) break; c_token++; if (almost_equals(c_token, "rgb$color")) { 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 (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 (allow_ls) { 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 (almost_equals(c_token, "pointt$ype") || equals(c_token, "pt")) { if (allow_point) { if (set_pt++) break; c_token++; 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; } /* 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) int_error(c_token, "duplicated arguments in style specification"); if (set_pal) { lp->pm3d_color = newlp.pm3d_color; lp->use_palette = newlp.use_palette; /* FIXME: This was used by hidden3d, but breaks contour coloring */ /* new_lt = LT_SINGLECOLOR; */ } if (set_lw) lp->l_width = newlp.l_width; if (set_pt) lp->p_type = newlp.p_type; 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; return new_lt; }
void arrow_parse( struct arrow_style_type *arrow, TBOOLEAN allow_as) { int set_layer=0, set_line=0, set_head=0; int set_headsize=0, set_headfilled=0; /* Use predefined arrow style */ if (allow_as && (almost_equals(c_token, "arrows$tyle") || equals(c_token, "as"))) { c_token++; if (almost_equals(c_token, "var$iable")) { arrow->tag = AS_VARIABLE; c_token++; } else { arrow_use_properties(arrow, int_expression()); } return; } /* No predefined arrow style; read properties from command line */ /* avoid duplicating options */ while (!END_OF_COMMAND) { if (equals(c_token, "nohead")) { if (set_head++) break; c_token++; arrow->head = NOHEAD; continue; } if (equals(c_token, "head")) { if (set_head++) break; c_token++; arrow->head = END_HEAD; continue; } if (equals(c_token, "backhead")) { if (set_head++) break; c_token++; arrow->head = BACKHEAD; continue; } if (equals(c_token, "heads")) { if (set_head++) break; c_token++; arrow->head = BACKHEAD | END_HEAD; continue; } if (almost_equals(c_token, "fill$ed")) { if (set_headfilled++) break; c_token++; arrow->head_filled = 2; continue; } if (almost_equals(c_token, "empty")) { if (set_headfilled++) break; c_token++; arrow->head_filled = 1; continue; } if (almost_equals(c_token, "nofill$ed")) { if (set_headfilled++) break; c_token++; arrow->head_filled = 0; continue; } if (equals(c_token, "size")) { struct position hsize; if (set_headsize++) break; hsize.scalex = hsize.scaley = hsize.scalez = first_axes; /* only scalex used; scaley is angle of the head in [deg] */ c_token++; if (END_OF_COMMAND) int_error(c_token, "head size expected"); get_position(&hsize); arrow->head_length = hsize.x; arrow->head_lengthunit = hsize.scalex; arrow->head_angle = hsize.y; arrow->head_backangle = hsize.z; /* invalid backangle --> default of 90.0 degrees */ if (arrow->head_backangle <= arrow->head_angle) arrow->head_backangle = 90.0; continue; } if (equals(c_token, "back")) { if (set_layer++) break; c_token++; arrow->layer = 0; continue; } if (equals(c_token, "front")) { if (set_layer++) break; c_token++; arrow->layer = 1; continue; } /* pick up a line spec - allow ls, but no point. */ { int stored_token = c_token; lp_parse(&arrow->lp_properties, TRUE, FALSE); if (stored_token == c_token || set_line++) break; continue; } /* unknown option caught -> quit the while(1) loop */ break; } if (set_layer>1 || set_line>1 || set_head>1 || set_headsize>1 || set_headfilled>1) int_error(c_token, "duplicated arguments in style specification"); }
/* * 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_LINESTYLE TC_RGB TC_CB TC_FRAC TC_Z TC_VARIABLE (0 1 2 3 4 5 6 7) * 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; } else if (equals(c_token,"bgnd")) { c_token++; tc->type = TC_LT; tc->lt = LT_BACKGROUND; } 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")) { c_token++; tc->type = TC_RGB; if (almost_equals(c_token, "var$iable")) { tc->value = -1.0; c_token++; } else { tc->value = 0.0; tc->lt = parse_color_name(); } } 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 if (options >= TC_VARIABLE && almost_equals(c_token,"var$iable")) { tc->type = TC_VARIABLE; c_token++; } else { int_error(c_token, "colorspec option not recognized"); } }
/* * 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"); } }
/* * 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; }
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; }
/* * 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_LINESTYLE TC_RGB TC_CB TC_FRAC TC_Z TC_VARIABLE (0 1 2 3 4 5 6 7) * 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; } else if (equals(c_token,"bgnd")) { c_token++; tc->type = TC_LT; tc->lt = LT_BACKGROUND; } else if (equals(c_token,"black")) { c_token++; tc->type = TC_LT; tc->lt = LT_BLACK; } else if (equals(c_token,"lt")) { struct lp_style_type lptemp; 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"); } /* * July 2014 - translate linetype into user-defined linetype color. * This is a CHANGE! * FIXME: calling load_linetype here may obviate the need to call it * many places in the higher level code. They could be removed. */ load_linetype(&lptemp, tc->lt + 1); *tc = lptemp.pm3d_color; } 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")) { c_token++; tc->type = TC_RGB; if (almost_equals(c_token, "var$iable")) { tc->value = -1.0; c_token++; } else { tc->value = 0.0; tc->lt = parse_color_name(); } } 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 if (options >= TC_VARIABLE && almost_equals(c_token,"var$iable")) { tc->type = TC_VARIABLE; c_token++; /* New: allow to skip the rgb keyword, as in 'plot $foo lc "blue"' */ } else if (isstring(c_token)) { tc->type = TC_RGB; tc->lt = parse_color_name(); } else { int_error(c_token, "colorspec option not recognized"); } }
void parse_fillstyle(struct fill_style_type *fs, int def_style, int def_density, int def_pattern, t_colorspec def_bordertype) { TBOOLEAN set_fill = FALSE; TBOOLEAN set_border = FALSE; TBOOLEAN transparent = FALSE; /* Set defaults */ fs->fillstyle = def_style; fs->filldensity = def_density; fs->fillpattern = def_pattern; fs->border_color = def_bordertype; if (END_OF_COMMAND) return; if (!equals(c_token, "fs") && !almost_equals(c_token, "fill$style")) return; c_token++; while (!END_OF_COMMAND) { int i; if (almost_equals(c_token, "trans$parent")) { transparent = TRUE; c_token++; continue; } i = lookup_table(fs_opt_tbl, c_token); switch (i) { default: break; case FS_EMPTY: case FS_SOLID: case FS_PATTERN: if (set_fill && fs->fillstyle != i) int_error(c_token, "conflicting option"); fs->fillstyle = i; set_fill = TRUE; c_token++; if (isanumber(c_token) || type_udv(c_token) == INTGR || type_udv(c_token) == CMPLX) { if (fs->fillstyle == FS_SOLID) { /* user sets 0...1, but is stored as an integer 0..100 */ fs->filldensity = 100.0 * real_expression() + 0.5; if (fs->filldensity < 0) fs->filldensity = 0; if (fs->filldensity > 100) fs->filldensity = 100; } else if (fs->fillstyle == FS_PATTERN) { fs->fillpattern = int_expression(); if (fs->fillpattern < 0) fs->fillpattern = 0; } else int_error(c_token, "this fill style does not have a parameter"); } continue; } if (almost_equals(c_token, "bo$rder")) { if (set_border && fs->border_color.lt == LT_NODRAW) int_error(c_token, "conflicting option"); fs->border_color.type = TC_DEFAULT; set_border = TRUE; c_token++; if (END_OF_COMMAND) continue; if (equals(c_token,"-") || isanumber(c_token)) { fs->border_color.type = TC_LT; fs->border_color.lt = int_expression() - 1; } else if (equals(c_token,"lc") || almost_equals(c_token,"linec$olor")) { parse_colorspec(&fs->border_color, TC_Z); } else if (equals(c_token,"rgb") || equals(c_token,"lt") || almost_equals(c_token,"linet$ype")) { c_token--; parse_colorspec(&fs->border_color, TC_Z); } continue; } else if (almost_equals(c_token, "nobo$rder")) { if (set_border && fs->border_color.lt != LT_NODRAW) int_error(c_token, "conflicting option"); fs->border_color.type = TC_LT; fs->border_color.lt = LT_NODRAW; set_border = TRUE; c_token++; continue; } /* Keyword must belong to someone else */ break; } if (transparent) { if (fs->fillstyle == FS_SOLID) fs->fillstyle = FS_TRANSPARENT_SOLID; else if (fs->fillstyle == FS_PATTERN) fs->fillstyle = FS_TRANSPARENT_PATTERN; } }
// 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); }
/* 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; }
/* * allow_ls controls whether we are allowed to accept linestyle in * the current context [ie not when doing a set linestyle command] * allow_point is whether we accept a point command * allow any order of options - pm 24.11.2001 * EAM Oct 2005 - Require that default values have been placed in lp by the caller */ void lp_parse(struct lp_style_type *lp, TBOOLEAN allow_ls, TBOOLEAN allow_point) { /* avoid duplicating options */ int set_lt = 0, set_pal = 0, set_lw = 0, set_pt = 0, set_ps = 0; if (allow_ls && (almost_equals(c_token, "lines$tyle") || equals(c_token, "ls"))) { c_token++; lp_use_properties(lp, int_expression()); } while (!END_OF_COMMAND) { if (almost_equals(c_token, "linet$ype") || equals(c_token, "lt")) { if (set_lt++) break; c_token++; if (almost_equals(c_token, "rgb$color")) { if (set_pal++) break; c_token--; parse_colorspec(&lp->pm3d_color, TC_RGB); lp->use_palette = 1; } 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(&lp->pm3d_color, TC_Z); lp->use_palette = 1; #ifdef KEYWORD_BGND } else if (equals(c_token,"bgnd")) { lp->l_type = LT_BACKGROUND; c_token++; #endif } else { int lt = int_expression(); lp->l_type = lt - 1; /* user may prefer explicit line styles */ if (prefer_line_styles && allow_ls) lp_use_properties(lp, 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(&lp->pm3d_color, TC_Z); lp->use_palette = 1; continue; } if (equals(c_token,"lc") || almost_equals(c_token,"linec$olor")) { lp->use_palette = 1; if (set_pal++) break; c_token++; if (almost_equals(c_token, "rgb$color")) { c_token--; parse_colorspec(&lp->pm3d_color, TC_RGB); } else if (almost_equals(c_token, "pal$ette")) { c_token--; parse_colorspec(&lp->pm3d_color, TC_Z); #ifdef KEYWORD_BGND } else if (equals(c_token,"bgnd")) { lp->pm3d_color.type = TC_LT; lp->pm3d_color.lt = LT_BACKGROUND; c_token++; #endif } else if (almost_equals(c_token, "var$iable")) { c_token++; lp->l_type = LT_COLORFROMCOLUMN; lp->pm3d_color.type = TC_LINESTYLE; } else { lp->pm3d_color.type = TC_LT; lp->pm3d_color.lt = int_expression() - 1; } continue; } if (almost_equals(c_token, "linew$idth") || equals(c_token, "lw")) { if (set_lw++) break; c_token++; lp->l_width = real_expression(); if (lp->l_width < 0) lp->l_width = 0; continue; } if (equals(c_token,"bgnd")) { lp->l_type = LT_BACKGROUND; lp->use_palette = 0; c_token++; continue; } if (almost_equals(c_token, "pointt$ype") || equals(c_token, "pt")) { if (allow_point) { if (set_pt++) break; c_token++; lp->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")) { lp->p_size = PTSZ_VARIABLE; c_token++; } else if (almost_equals(c_token, "def$ault")) { lp->p_size = PTSZ_DEFAULT; c_token++; } else { lp->p_size = real_expression(); if (lp->p_size < 0) lp->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) { lp->p_interval = int_expression(); } else { int_warn(c_token, "No pointinterval specifier allowed, here"); int_expression(); } continue; } /* unknown option catched -> quit the while(1) loop */ break; } if (set_lt > 1 || set_pal > 1 || set_lw > 1 || set_pt > 1 || set_ps > 1) int_error(c_token, "duplicated arguments in style specification"); }