home *** CD-ROM | disk | FTP | other *** search
- From: fs@uwasa.fi (Filip Sawicki LAKE)
- Newsgroups: alt.sources
- Subject: Fchart part 02/04
- Message-ID: <1990Jun4.125148.1181@uwasa.fi>
- Date: 4 Jun 90 12:51:48 GMT
-
- Submitted-by: fs@chyde
- Archive-name: Fchart/part02
-
- #!/bin/sh
- # This is part 02 of Fchart
- if touch 2>&1 | fgrep '[-amc]' > /dev/null
- then TOUCH=touch
- else TOUCH=true
- fi
- # ============= fcmd.c ==============
- echo "x - extracting fcmd.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > fcmd.c &&
- X/* Fchart - fcmd.c */
- X/*
- X * Gnuplot code
- X * Copyright (C) 1986, 1987, 1990 Thomas Williams, Colin Kelley
- X *
- X * Permission to use, copy, and distribute this software and its
- X * documentation for any purpose with or without fee is hereby granted,
- X * provided that the above copyright notice appear in all copies and
- X * that both that copyright notice and this permission notice appear
- X * in supporting documentation.
- X *
- X * Permission to modify the software is granted, but not the right to
- X * distribute the modified code. Modifications are to be distributed
- X * as patches to released version.
- X *
- X * This software is provided "as is" without express or implied warranty.
- X *
- X *
- X * AUTHORS
- X *
- X * Original Software:
- X * Thomas Williams, Colin Kelley.
- X *
- X * Gnuplot 2.0 additions:
- X * Russell Lang, Dave Kotz, John Campbell.
- X *
- X * Fchart changes and additions:
- X * Piotr Filip Sawicki
- X *
- X * send your comments or suggestions to fs@uwasa.fi
- X *
- X */
- X#include <stdio.h>
- X#include <math.h>
- X#include <ctype.h>
- X
- X#ifdef MSDOS
- X#include <process.h>
- X
- X#ifdef __ZTC__
- X#define P_WAIT 0
- X#include <time.h> /* usleep() */
- X#else
- X
- X#ifdef __TURBOC__
- X#include <dos.h> /* sleep() */
- X
- X#else /* must be MSC */
- X#include <time.h> /* kludge to provide sleep() */
- Xvoid sleep(); /* defined later */
- X#endif /* TURBOC */
- X#endif /* ZTC */
- X
- X#endif /* MSDOS */
- X
- X#include "plot.h"
- X#include "fchart.h"
- X#include "help.h"
- X
- X#ifndef STDOUT
- X#define STDOUT 1
- X#endif
- X
- X#ifndef HELPFILE
- X#define HELPFILE "fchart.gih" /* changed by makefile */
- X#endif
- X
- X/* global defs for default values */
- X#define DEF_T_FORMAT "%g" /* make it as narrow as possible */
- X#define EXPL_RAD 0.3 /* ratio of explosion of a slice */
- X#define MAXBARWIDTH 0.2 /* default maximal allowable width of bar */
- X#define INTERBAR 0.2 /* interbar space in terms of real bar width */
- X#define INTERGROUP 0.5 /* space between groups of bars */
- X#define OTHER "other" /* name for combined slice */
- X
- X/*
- X * global variables to hold status of 'set' options
- X *
- X */
- X
- XBOOLEAN autoscale = TRUE,
- X auto_label = FALSE,
- X p_clockwise = TRUE,
- X b_clockwise = TRUE,
- X draw_border = TRUE;
- X
- Xenum DRAW_STYLE data_style = ABARS;
- Xenum GRAV_DIR gravity = SOUTH,
- X explode = DEFAULT;
- Xenum INP_STYLE inp_style = PRIVATE;
- Xenum FONT_STYLE vect_font = F_WHENN;
- XBOOLEAN log_y = FALSE;
- XFILE* outfile;
- Xchar outstr[MAX_LINE_LEN+1] = "STDOUT";
- Xint samples = SAMPLES;
- Xint term = 0; /* unknown term is 0 */
- Xint xmin = -1,
- X xmax = -1;
- Xdouble base = 0.0;
- Xdouble loff = 0.0,
- X roff = 0.0,
- X toff = 0.0,
- X boff = 0.0;
- Xdouble b_wid = MAXBARWIDTH,
- X b_int = INTERBAR,
- X b_spc = INTERGROUP;
- Xdouble radexp = EXPL_RAD; /* explosion power */
- Xdouble zero = ZERO; /* zero threshold, not 0! */
- Xint HLitem = HL_NON; /* no highliting by default */
- Xstruct pair data_place = { -1, -1 }, /* not defined yet */
- X label_plac = { -1, -1 }; /* not defined yet */
- Xfloat xsize = 1.0,
- X ysize = 1.0;
- Xdouble treshold = 0.0;
- Xchar thrname[MAX_LINE_LEN+1] = OTHER;
- Xchar tic_form[MAX_LINE_LEN+1] = DEF_T_FORMAT;
- Xint strunc = -1;
- X
- Xstruct dfile data_head = { NULL, 0.0, 0.0, 0, 0, HL_NON, FALSE, NULL, NULL } ;
- X
- XBOOLEAN screen_ok;
- XBOOLEAN term_init;
- X/* BOOLEAN undefined; */ /* probably not even used */
- X
- X/*
- X * instead of <strings.h>
- X */
- X
- Xchar *gets(),*getenv(),*sprintf(); /* for lint only */
- Xchar *strcpy(),*strncpy(),*strcat();
- X
- Xextern double real();
- Xextern void set_label(), set_nolabel(), set_arrow(), set_noarrow();
- Xextern void show_labels(), show_arrow();
- X
- Xextern struct termentry term_tbl[];
- X
- Xstruct lexical_unit token[MAX_TOKENS];
- Xchar input_line[MAX_LINE_LEN+1] = "";
- Xint num_tokens, c_token;
- X
- Xstatic char replot_line[MAX_LINE_LEN+1];
- Xstatic int plot_token; /* start of 'plot' command */
- X
- Xextern void squash_spaces(), lower_case();
- X
- Xcom_line()
- X{
- X read_line(PROMPT);
- X
- X screen_ok = interactive; /* see 'Gnuplot' why */
- X
- X do_line();
- X}
- X
- X
- Xdo_line() /* also used in load_file */
- X{
- X if (is_system(input_line[0])) {
- X do_system();
- X fputs("!\n",stderr);
- X return;
- X }
- X num_tokens = scanner(input_line);
- X c_token = 0;
- X while(c_token < num_tokens) {
- X command();
- X if (c_token < num_tokens) /* something after command */
- X if (equals(c_token,";"))
- X c_token++;
- X else
- X int_error("';' expected",c_token);
- X }
- X}
- X
- Xcommand()
- X{
- X static char sv_file[MAX_LINE_LEN+1];
- X /* string holding name of save or load file */
- X
- X if (equals(c_token,"help") || equals(c_token,"?")) {
- X c_token++;
- X do_help();
- X }
- X else if (almost_equals(c_token,"test")) {
- X c_token++;
- X term_test();
- X }
- X else if (almost_equals(c_token,"pa$use")) {
- X int stime=1, text=0;
- X char buf[MAX_LINE_LEN+1];
- X
- X c_token++;
- X if (equals(c_token,"-")) stime=-1, c_token++;
- X stime *= (int)real(c_token);
- X c_token++;
- X if (!(END_OF_COMMAND)) {
- X if (!isstring(c_token))
- X int_error("expecting string",c_token);
- X else {
- X quote_str(buf,c_token);
- X fprintf (stderr, "%s",buf);
- X text = 1;
- X }
- X }
- X if (stime < 0) fgets (buf,MAX_LINE_LEN,stdin); /* Hold until CR hit */
- X#ifdef __ZTC__
- X if (stime > 0) usleep((unsigned long) stime);
- X#else
- X if (stime > 0) sleep((unsigned) stime);
- X#endif
- X if (text != 0 && stime >= 0) fprintf (stderr,"\n");
- X c_token++;
- X screen_ok = FALSE;
- X }
- X else if (almost_equals(c_token,"p$lot") ||
- X almost_equals(c_token,"d$raw")) {
- X plot_token = c_token++;
- X plotrequest(FALSE);
- X }
- X else if (almost_equals(c_token,"tp$lot") ||
- X almost_equals(c_token,"td$raw") ||
- X almost_equals(c_token,"xp$lot") || /* for backward compatibility */
- X almost_equals(c_token,"xd$raw") || /* for backward compatibility */
- X almost_equals(c_token,"trans_plot") ||
- X almost_equals(c_token,"trans_draw")) {
- X plot_token = c_token++;
- X plotrequest(TRUE);
- X }
- X else if (almost_equals(c_token,"rep$lot") ||
- X almost_equals(c_token,"red$raw")) {
- X c_token++;
- X if (replot_line[0] == '\0')
- X int_error("no previous plot",c_token);
- X if (!END_OF_COMMAND) {
- X char str[MAX_LINE_LEN+1];
- X capture(str,c_token,num_tokens-1);
- X if ((strlen(str)+strlen(input_line)) <= MAX_LINE_LEN-1) {
- X (void) strcat(replot_line,",");
- X (void) strcat(replot_line,str);
- X }
- X else
- X int_error("plot line too long with replot arguments",c_token);
- X }
- X (void) strcpy(input_line,replot_line);
- X screen_ok = FALSE;
- X num_tokens = scanner(input_line);
- X c_token = 1; /* skip the 'plot' part */
- X plotrequest(almost_equals(0,"td$raw") ||
- X almost_equals(0,"tp$lot") ||
- X almost_equals(0,"xd$raw") ||
- X almost_equals(0,"xp$lot") ||
- X almost_equals(0,"tr$ans_plot") ||
- X almost_equals(0,"tr$ans_draw")); /* fetch plot type */
- X }
- X else if (almost_equals(c_token,"se$t"))
- X set_stuff();
- X else if (almost_equals(c_token,"sh$ow"))
- X show_stuff();
- X else if (almost_equals(c_token,"sa$ve")) {
- X c_token++;
- X if (END_OF_COMMAND || !isstring(c_token))
- X int_error("name of file expected", c_token);
- X quote_str(sv_file,c_token);
- X save_sets(fopen(sv_file,"w"));
- X /* c_token updated in save_sets */
- X }
- X else if (almost_equals(c_token,"cl$ear")) {
- X if (!term_init) {
- X (*term_tbl[term].init)();
- X term_init = TRUE;
- X }
- X (*term_tbl[term].graphics)();
- X (*term_tbl[term].text)();
- X (void) fflush(outfile);
- X screen_ok = FALSE;
- X c_token++;
- X }
- X else if (almost_equals(c_token,"she$ll")) {
- X do_shell();
- X screen_ok = FALSE;
- X c_token++;
- X }
- X else if (almost_equals(c_token,"l$oad") ||
- X almost_equals(c_token,"r$ead")) {
- X if (!isstring(++c_token))
- X int_error("expecting filename",c_token);
- X else {
- X quote_str(sv_file,c_token);
- X load_file(fopen(sv_file,"r"));
- X /* input_line[] and token[] now destroyed! */
- X c_token = num_tokens = 0;
- X }
- X }
- X else if (almost_equals(c_token,"ex$it") ||
- X almost_equals(c_token,"q$uit")) {
- X done(IO_SUCCESS);
- X }
- X else if (!equals(c_token,";")) { /* null statement */
- X int_error("Invalid command. Try:\n\
- X'?/help', 'test', 'pause', '[t]draw/[t]plot',\n\
- X'replot/redraw', 'set', 'show', 'save', 'shell',\n\
- X'load/read', 'exit/quit'",c_token);
- X }
- X}
- X
- X
- Xenum DRAW_STYLE
- Xget_style()
- X{
- Xregister enum DRAW_STYLE ps;
- X
- X c_token++;
- X if (almost_equals(c_token,"a$djacent_bars"))
- X ps = ABARS;
- X else if (almost_equals(c_token,"l$ayer_bars"))
- X ps = LAYB;
- X else if (almost_equals(c_token,"s$tacked_bars"))
- X ps = SBAR;
- X else if (almost_equals(c_token,"p$iechart"))
- X ps = PIECHART;
- X else
- X int_error("expecting 'adjacent_bars', 'stacked_bars', 'layer_bars' or 'piechart'",c_token);
- X c_token++;
- X return(ps);
- X}
- X
- Xenum GRAV_DIR
- Xget_gravity()
- X{
- X c_token++;
- X if (END_OF_COMMAND) return(DEFAULT);
- X else if (almost_equals(c_token,"b$ottom") || almost_equals(c_token,"s$outh")) {
- X c_token++;
- X return(SOUTH);
- X }
- X else if (almost_equals(c_token,"t$op") || almost_equals(c_token,"n$orth")) {
- X c_token++;
- X return(NORTH);
- X }
- X else if (almost_equals(c_token,"l$eft") || almost_equals(c_token,"w$est")) {
- X c_token++;
- X return(WEST);
- X }
- X else if (almost_equals(c_token,"r$ight") || almost_equals(c_token,"e$ast")) {
- X c_token++;
- X return(EAST);
- X }
- X else
- X int_error("expecting direction: 'left/west', 'right/east',\n'bottom/south' or 'top/north'",c_token);
- X /*NOTREACHED*/
- X}
- X
- Xenum INP_STYLE
- Xget_input()
- X{
- X if (END_OF_COMMAND) return(PRIVATE);
- X else if (almost_equals(c_token,"g$nuplot")) {
- X c_token++;
- X return(GNUPLOT);
- X }
- X else if (almost_equals(c_token,"p$rivate")) {
- X c_token++;
- X return(PRIVATE);
- X }
- X else if (almost_equals(c_token,"c$ustomized")) {
- X c_token++;
- X return(CUSTOMD);
- X }
- X else
- X int_error("expected 'gnuplot', 'private' or 'customized'",c_token);
- X /*NOTREACHED*/
- X}
- X
- Xset_stuff()
- X{
- X static char testfile[MAX_LINE_LEN+1];
- X
- X if (almost_equals(++c_token,"b$ar")) {
- X set_bar_stuff();
- X }
- X else if (almost_equals(c_token,"fr$ame")) {
- X draw_border = TRUE;
- X c_token++;
- X }
- X else if (almost_equals(c_token,"nof$rame")) {
- X draw_border = FALSE;
- X c_token++;
- X }
- X else if (almost_equals(c_token,"for$mat")) {
- X c_token++;
- X if (END_OF_COMMAND)
- X (void) strcpy(tic_form, DEF_T_FORMAT);
- X else if (!isstring(c_token))
- X int_error("enquoted format expected", c_token);
- X else
- X quote_str(tic_form, c_token++);
- X }
- X else if (almost_equals(c_token,"fon$t")) {
- X c_token++;
- X if (END_OF_COMMAND)
- X vect_font = F_ALWYS;
- X else {
- X if (almost_equals(c_token,"n$ever"))
- X vect_font = F_NEVER;
- X else if (almost_equals(c_token,"w$hen_needed"))
- X vect_font = F_WHENN;
- X else if (almost_equals(c_token,"r$otated"))
- X vect_font = F_ROTAT;
- X else if (almost_equals(c_token,"a$lways"))
- X vect_font = F_ALWYS;
- X else
- X int_error("'never', 'when_needed', 'rotated', or 'always' expected",c_token);
- X c_token++;
- X }
- X }
- X else if (almost_equals(c_token,"au$tolabeling")) {
- X auto_label = TRUE;
- X c_token++;
- X }
- X else if (almost_equals(c_token,"noau$tolabeling")) {
- X auto_label = FALSE;
- X c_token++;
- X }
- X else if (almost_equals(c_token,"ar$row")) {
- X c_token++;
- X set_arrow(TRUE);
- X }
- X else if (almost_equals(c_token,"noar$row")) {
- X c_token++;
- X set_noarrow();
- X }
- X else if (almost_equals(c_token,"c$ustomized")) {
- X c_token++;
- X if (END_OF_COMMAND) {
- X data_place.from = -1; /* not defined */
- X label_plac.from = -1; /* thus no label */
- X }
- X else {
- X if (!equals(c_token,"["))
- X int_error("expecting '['",c_token);
- X c_token++;
- X load_range(&data_place.from,&data_place.upto);
- X if (!equals(c_token,"]"))
- X int_error("expecting ']'",c_token);
- X c_token++;
- X if (END_OF_COMMAND)
- X label_plac.from = -1; /* no label */
- X else {
- X if (equals(c_token,",")) c_token++; /* optional ',' */
- X if (!equals(c_token,"["))
- X int_error("expecting '['",c_token);
- X c_token++;
- X load_range(&label_plac.from,&label_plac.upto);
- X if (!equals(c_token,"]"))
- X int_error("expected ']'",c_token);
- X c_token++;
- X }
- X if (!check_ranges(&data_place,&label_plac)) { /* overlapping ranges ? */
- X data_place.from = label_plac.from = -1;
- X int_error("value and label places are overlapping or are empty",NO_CARET);
- X }
- X }
- X }
- X else if (almost_equals(c_token,"h$ighlight")) {
- X c_token++;
- X HLitem = get_HL();
- X }
- X else if (almost_equals(c_token,"i$nput")) {
- X c_token++;
- X inp_style = get_input();
- X }
- X else if (almost_equals(c_token,"lo$gscale")) {
- X c_token++;
- X log_y = TRUE;
- X }
- X else if (almost_equals(c_token,"nolo$gscale")) {
- X log_y = FALSE;
- X c_token++;
- X }
- X else if (almost_equals(c_token,"la$bel")) {
- X c_token++;
- X set_label();
- X }
- X else if (almost_equals(c_token,"nola$bel")) {
- X c_token++;
- X set_nolabel();
- X }
- X else if (almost_equals(c_token,"li$ne")) {
- X c_token++;
- X set_arrow(FALSE);
- X }
- X else if (almost_equals(c_token,"noli$ne")) {
- X c_token++;
- X set_noarrow();
- X }
- X else if (almost_equals(c_token,"of$fsets")) {
- X c_token++;
- X if (END_OF_COMMAND) {
- X loff = roff = toff = boff = 0.0; /* Reset offsets */
- X }
- X else {
- X load_offsets (&loff,&roff,&toff,&boff);
- X if ((loff>1.0 ? loff/100.0 : loff) + (roff>1.0 ? roff/100.0 : roff) >= 1.0 ||
- X (boff>1.0 ? boff/100.0 : boff) + (toff>1.0 ? toff/100.0 : toff) >= 1.0) {
- X loff = roff = toff = boff = 0.0; /* Reset offsets for the future */
- X int_error("null picture size within given offsets",NO_CARET);
- X }
- X }
- X }
- X else if (almost_equals(c_token,"o$utput")) {
- X register FILE *f;
- X
- X c_token++;
- X if (END_OF_COMMAND) { /* no file specified */
- X UP_redirect (4);
- X if (outfile != stdout) /* Never close stdout */
- X (void) fclose(outfile);
- X outfile = stdout; /* Avoid the dup... */
- X term_init = FALSE;
- X (void) strcpy(outstr,"STDOUT");
- X } else if (!isstring(c_token))
- X int_error("expecting filename",c_token);
- X else {
- X quote_str(testfile,c_token);
- X if (!(f = fopen(testfile,"w"))) {
- X os_error("cannot open file; output not changed",c_token);
- X }
- X if (outfile != stdout) /* Never close stdout */
- X (void) fclose(outfile);
- X outfile = f;
- X term_init = FALSE;
- X outstr[0] = '\'';
- X (void) strcat(strcpy(outstr+1,testfile),"'");
- X UP_redirect (1);
- X }
- X c_token++;
- X }
- X else if (almost_equals(c_token,"p$ie")) {
- X set_pie_stuff();
- X }
- X else if (almost_equals(c_token,"si$ze")) {
- X c_token++;
- X if (END_OF_COMMAND) {
- X xsize = 1.0;
- X ysize = 1.0;
- X }
- X else {
- X xsize = (float)real(c_token);
- X c_token++;
- X if (!equals(c_token,","))
- X int_error("',' expected",c_token);
- X c_token++;
- X if (END_OF_COMMAND)
- X int_error("value for ysize expected",c_token);
- X ysize = (float)real(c_token);
- X c_token++;
- X }
- X }
- X else if (almost_equals(c_token,"st$yle")) {
- X data_style = get_style();
- X }
- X else if (almost_equals(c_token,"te$rminal")) {
- X c_token++;
- X if (END_OF_COMMAND) {
- X list_terms();
- X screen_ok = FALSE;
- X }
- X else {
- X if (term && term_init) {
- X (*term_tbl[term].reset)();
- X (void) fflush(outfile);
- X }
- X term = set_term(c_token);
- X c_token++;
- X }
- X }
- X else if (almost_equals(c_token,"ti$tle")) {
- X c_token++;
- X if (END_OF_COMMAND) {
- X if (data_head.fname)
- X free(data_head.fname);
- X data_head.fname = NULL;
- X }
- X else if (isstring(c_token)) {
- X m_quote_capture(&(data_head.fname), c_token, c_token);
- X c_token++;
- X }
- X else
- X int_error("title within quotes expected", c_token);
- X }
- X else if (almost_equals(c_token,"tr$uncate")) {
- X c_token++;
- X if (END_OF_COMMAND)
- X strunc = 0;
- X else {
- X strunc = real(c_token);
- X c_token++;
- X }
- X }
- X else if (almost_equals(c_token,"not$runcate")) {
- X c_token++;
- X strunc = -1;
- X }
- X else if (almost_equals(c_token,"r$ange")) {
- X c_token++;
- X if (END_OF_COMMAND) xmin=-1;
- X else {
- X if (!equals(c_token,"["))
- X int_error("expecting '['",c_token);
- X c_token++;
- X load_range(&xmin,&xmax);
- X if (!equals(c_token,"]"))
- X int_error("expecting ']'",c_token);
- X c_token++;
- X if (xmax != -1 && xmax < xmin) {
- X xmin = -1; /* whole */
- X int_error("given range is empty",NO_CARET);
- X }
- X }
- X }
- X else if (almost_equals(c_token,"z$ero") ||
- X almost_equals(c_token,"eps$ilon")) {
- X int sign=1;
- X c_token++;
- X if (equals(c_token,"-")) sign=-1, c_token++;
- X zero = sign*real(c_token);
- X c_token++;
- X }
- X else
- X int_error(
- X "valid set options: 'bar', '[no]logscale',\n\
- X'customized', 'format', 'highlight', 'offsets'\n\
- X'output', 'pie', 'style', '[no]autolabeling',\n\
- X'terminal', 'title', 'range', 'zero/epsilon',\n\
- X'[no]frame', 'font', '[no]truncate', '[no]label',\n\
- X'[no]arrow', '[no]line'",
- X c_token);
- X}
- X
- Xset_bar_stuff()
- X{
- X if (almost_equals(++c_token,"a$utoscale")) {
- X autoscale = TRUE;
- X c_token++;
- X }
- X else if (almost_equals(c_token,"noa$utoscale")) {
- X autoscale = FALSE;
- X c_token++;
- X }
- X else if (almost_equals(c_token,"b$ase")) {
- X int sign = 1;
- X c_token++;
- X if (END_OF_COMMAND) base = 0.0;
- X else {
- X if (equals(c_token,"-")) c_token++, sign=-1;
- X base = sign*real(c_token);
- X c_token++;
- X }
- X }
- X else if (almost_equals(c_token,"cl$ockwise")) {
- X b_clockwise = TRUE;
- X c_token++;
- X }
- X else if (almost_equals(c_token,"co$unter_clockwise")) {
- X b_clockwise = FALSE;
- X c_token++;
- X }
- X else if (almost_equals(c_token,"g$ravitation")) {
- X gravity = get_gravity();
- X if (gravity==DEFAULT) gravity = SOUTH;
- X }
- X else if (almost_equals(c_token,"w$idth")) {
- X c_token++;
- X if (END_OF_COMMAND) {
- X b_wid = MAXBARWIDTH;
- X b_int = INTERBAR;
- X b_spc = INTERGROUP;
- X }
- X else
- X load_offsets(&b_wid, &b_int, &b_spc, (double *) NULL);
- X }
- X else
- X int_error("valid options: '[no]autoscale', 'base',\n\
- X'[counter_]clockwise', 'gravitation', 'width'",c_token);
- X}
- X
- Xset_pie_stuff()
- X{
- X if (almost_equals(++c_token,"ex$plode")) {
- X explode = get_gravity();
- X }
- X else if (almost_equals(c_token,"cl$ockwise")) {
- X p_clockwise = TRUE;
- X c_token++;
- X }
- X else if (almost_equals(c_token,"co$unter_clockwise")) {
- X p_clockwise = FALSE;
- X c_token++;
- X }
- X else if (almost_equals(c_token,"r$adius")) {
- X c_token++;
- X if (END_OF_COMMAND)
- X radexp = EXPL_RAD;
- X else {
- X radexp = real(c_token);
- X c_token++;
- X }
- X }
- X else if (almost_equals(c_token,"s$amples")) {
- X register int tsamp;
- X
- X c_token++;
- X tsamp = (int)real(c_token);
- X if (tsamp < 1)
- X int_error("sampling rate must be > 0; sampling unchanged",
- X c_token);
- X else samples = tsamp;
- X c_token++;
- X }
- X else if (almost_equals(c_token,"t$hreshold")) {
- X c_token++;
- X if (END_OF_COMMAND) {
- X treshold = 0.0;
- X strcpy(thrname, OTHER);
- X }
- X else {
- X treshold = real(c_token);
- X c_token++;
- X if (END_OF_COMMAND)
- X strcpy(thrname, OTHER);
- X else if (!isstring(c_token))
- X int_error("name in quotes expected", c_token);
- X else {
- X quote_str(thrname, c_token);
- X c_token++;
- X }
- X }
- X }
- X else
- X int_error("valid options: '[counter_]clockwise',\n\
- X'explode', 'radius', 'samples', 'threshold'",c_token);
- X}
- X
- Xget_HL()
- X{
- X if (END_OF_COMMAND) return(HL_NON);
- X else if (almost_equals(c_token,"n$one")) {
- X c_token++;
- X return(HL_NON);
- X }
- X else if (almost_equals(c_token,"mi$nim")) {
- X c_token++;
- X return(HL_MIN);
- X }
- X else if (almost_equals(c_token,"ma$xim")) {
- X c_token++;
- X return(HL_MAX);
- X }
- X else if (isnumber(c_token)) {
- X return((int) real(c_token++));
- X }
- X else
- X int_error("'maximum', 'minimum', 'none' or number expected",c_token);
- X /*NOTREACHED*/
- X}
- X
- Xshow_stuff()
- X{
- X if (almost_equals(++c_token,"sc$ale")) {
- X (void) putc('\n',stderr);
- X show_autoscale();
- X c_token++;
- X }
- X else if (almost_equals(c_token,"au$tolabeling")) {
- X (void) putc('\n',stderr);
- X show_label();
- X c_token++;
- X }
- X else if (almost_equals(c_token,"lo$gscale")) {
- X (void) putc('\n',stderr);
- X show_logscale();
- X c_token++;
- X }
- X else if (almost_equals(c_token,"la$bel")) {
- X (void) putc('\n',stderr);
- X c_token++;
- X if (END_OF_COMMAND)
- X show_labels(0, stderr, FALSE);
- X else {
- X show_labels((int)real(c_token), stderr, FALSE);
- X c_token++;
- X }
- X }
- X else if (almost_equals(c_token,"li$ne") || almost_equals(c_token,"ar$row")) {
- X (void) putc('\n',stderr);
- X c_token++;
- X if (END_OF_COMMAND)
- X show_arrow(0, stderr, FALSE);
- X else {
- X show_arrow((int)real(c_token), stderr, FALSE);
- X c_token++;
- X }
- X }
- X else if (almost_equals(c_token,"bas$e")) {
- X (void) putc('\n',stderr);
- X show_base();
- X c_token++;
- X }
- X else if (almost_equals(c_token,"fr$ame")) {
- X (void) putc('\n',stderr);
- X show_border();
- X c_token++;
- X }
- X else if (almost_equals(c_token,"for$mat")) {
- X (void) putc('\n',stderr);
- X show_format();
- X c_token++;
- X }
- X else if (almost_equals(c_token,"fon$t")) {
- X (void) putc('\n',stderr);
- X show_font();
- X c_token++;
- X }
- X else if (almost_equals(c_token,"cl$ockwise")) {
- X (void) putc('\n',stderr);
- X show_clock(TRUE);
- X show_clock(FALSE);
- X c_token++;
- X }
- X else if (almost_equals(c_token,"cu$stomized")) {
- X (void) putc('\n',stderr);
- X show_custom();
- X c_token++;
- X }
- X else if (almost_equals(c_token,"ex$plode")) {
- X (void) putc('\n',stderr);
- X show_explode();
- X c_token++;
- X }
- X else if (almost_equals(c_token,"gr$avitation")) {
- X (void) putc('\n',stderr);
- X show_gravity();
- X c_token++;
- X }
- X else if (almost_equals(c_token,"h$ighlight")) {
- X (void) putc('\n',stderr);
- X show_HLset();
- X c_token++;
- X }
- X else if (almost_equals(c_token,"i$nput")) {
- X (void) putc('\n',stderr);
- X show_input();
- X c_token++;
- X }
- X else if (almost_equals(c_token,"of$fsets")) {
- X (void) putc('\n',stderr);
- X show_offsets();
- X c_token++;
- X }
- X else if (almost_equals(c_token,"o$utput")) {
- X (void) putc('\n',stderr);
- X show_output();
- X c_token++;
- X }
- X else if (almost_equals(c_token,"sa$mples")) {
- X (void) putc('\n',stderr);
- X show_samples();
- X c_token++;
- X }
- X else if (almost_equals(c_token,"st$yle")) {
- X (void) putc('\n',stderr);
- X c_token++;
- X show_style();
- X }
- X else if (almost_equals(c_token,"si$ze")) {
- X (void) putc('\n',stderr);
- X c_token++;
- X show_size();
- X }
- X else if (almost_equals(c_token,"te$rminal")) {
- X (void) putc('\n',stderr);
- X show_term();
- X c_token++;
- X }
- X else if (almost_equals(c_token,"ti$tle")) {
- X (void) putc('\n',stderr);
- X show_title();
- X c_token++;
- X }
- X else if (almost_equals(c_token,"th$reshold")) {
- X (void) putc('\n',stderr);
- X show_tresh();
- X c_token++;
- X }
- X else if (almost_equals(c_token,"tr$uncate")) {
- X (void) putc('\n',stderr);
- X show_trunc();
- X c_token++;
- X }
- X else if (almost_equals(c_token,"w$idth")) {
- X (void) putc('\n',stderr);
- X show_width();
- X c_token++;
- X }
- X else if (almost_equals(c_token,"ve$rsion")) {
- X show_version();
- X c_token++;
- X }
- X else if (almost_equals(c_token,"rad$ius")) {
- X (void) putc('\n',stderr);
- X show_radius();
- X c_token++;
- X }
- X else if (almost_equals(c_token,"r$ange")) {
- X (void) putc('\n',stderr);
- X show_range();
- X c_token++;
- X }
- X else if (almost_equals(c_token,"z$ero") ||
- X almost_equals(c_token,"eps$ilon")) {
- X (void) putc('\n',stderr);
- X show_zero();
- X c_token++;
- X }
- X else if (almost_equals(c_token,"g$eneral")) { /* no more !!! */
- X c_token++;
- X show_version();
- X show_input();
- X show_custom();
- X show_range();
- X show_label();
- X show_trunc();
- X show_output();
- X show_term();
- X show_size();
- X show_offsets();
- X show_border();
- X show_font();
- X show_title();
- X show_labels(0, stderr, FALSE);
- X show_arrow(0, stderr, FALSE);
- X show_logscale();
- X show_format();
- X show_zero();
- X show_HLset();
- X show_style();
- X }
- X else if (almost_equals(c_token,"bar$charts")) {
- X c_token++;
- X show_version();
- X show_style();
- X fprintf(stderr,"\n\tsettings for barcharts (any bar style):\n\n");
- X show_base();
- X show_width();
- X show_autoscale();
- X show_gravity();
- X show_clock(FALSE);
- X }
- X else if (almost_equals(c_token,"pie$charts")) {
- X c_token++;
- X show_version();
- X show_style();
- X fprintf(stderr,"\n\tsettings for piecharts:\n\n");
- X show_clock(TRUE);
- X show_explode();
- X show_radius();
- X show_tresh();
- X show_samples();
- X }
- X else if (almost_equals(c_token,"a$ll")) {
- X c_token++;
- X show_version();
- X show_input();
- X show_custom();
- X show_range();
- X show_label();
- X show_trunc();
- X show_output();
- X show_term();
- X show_size();
- X show_offsets();
- X show_border();
- X show_font();
- X show_title();
- X show_labels(0, stderr, FALSE);
- X show_arrow(0, stderr, FALSE);
- X show_logscale();
- X show_format();
- X show_zero();
- X show_HLset();
- X show_style();
- X show_base();
- X show_width();
- X show_autoscale();
- X show_gravity();
- X show_clock(FALSE); /* bars */
- X show_clock(TRUE); /* pies */
- X show_explode();
- X show_radius();
- X show_tresh();
- X show_samples();
- X }
- X else
- X int_error(
- X "valid show options: 'all', 'scale', 'base', 'font'\n\
- X'customized', 'explode', 'gravitation', 'highlight',\n\
- X'input', 'logscale', 'offsets', 'output', 'label',\n\
- X'samples', 'style', 'terminal', 'version', 'range',\n\
- X'radius', 'clockwise', 'width', 'zero/epsilon', 'frame',\n\
- X'size', 'general', 'barcharts', 'piecharts', 'format',\n\
- X'threshold', 'truncate', 'line', 'arrow', 'autolabeling'",
- Xc_token);
- X screen_ok = FALSE;
- X (void) putc('\n',stderr);
- X}
- X
- X
- Xload_offsets (a, b, c, d)
- Xdouble *a, *b, *c, *d;
- X{
- X *a = real (c_token); /* loff value */
- X if (*a >= 100.0 && d)
- X int_error("value <0,100) expected",c_token);
- X c_token++;
- X if (equals(c_token,","))
- X c_token++;
- X if (END_OF_COMMAND)
- X return;
- X
- X *b = real (c_token); /* roff value */
- X if (*b >= 100.0 && d)
- X int_error("value <0,100) expected",c_token);
- X c_token++;
- X if (equals(c_token,","))
- X c_token++;
- X if (END_OF_COMMAND)
- X return;
- X
- X *c = real (c_token); /* toff value */
- X if (*c >= 100.0 && d)
- X int_error("value <0,100) expected",c_token);
- X c_token++;
- X
- X if (!d) return;
- X if (equals(c_token,","))
- X c_token++;
- X if (END_OF_COMMAND)
- X return;
- X
- X *d = real (c_token); /* boff value */
- X if (*d >= 100.0)
- X int_error("value <0,100) expected",c_token);
- X c_token++;
- X}
- X
- X
- Xload_range(a,b)
- Xint *a, *b;
- X{
- X if (equals(c_token,"]"))
- X return; /* no change */
- X if (END_OF_COMMAND) {
- X int_error("starting range value or ':' expected",c_token);
- X } else if (!equals(c_token,"to") && !equals(c_token,":")) {
- X *a = (int)real(c_token);
- X c_token++;
- X }
- X else *a = 0; /* from the very begining */
- X if (!equals(c_token,"to") && !equals(c_token,":"))
- X int_error("':' expected",c_token);
- X c_token++;
- X if (!equals(c_token,"]")) {
- X *b = (int)real(c_token);
- X c_token++;
- X }
- X else *b = -1; /* to infinity */
- X}
- X
- X
- Xplotrequest(xplot)
- XBOOLEAN xplot;
- X{
- X
- X if (!term) /* unknown */
- X int_error("use 'set term' to set terminal type first",c_token);
- X
- X if (log_y && base<1.0 && data_style != PIECHART)
- X int_error("base for bars out of range for logscale",NO_CARET);
- X
- X if (equals(c_token,"[")) {
- X c_token++;
- X load_range(&xmin,&xmax);
- X if (!equals(c_token,"]"))
- X int_error("']' expected",c_token);
- X c_token++;
- X if (xmax != -1 && xmax < xmin)
- X int_error("given range is empty",NO_CARET);
- X }
- X
- X eval_plots(xplot);
- X}
- X
- Xint missing(s)
- Xchar *s;
- X/* check if s represents a missing value (spaces and dot) */
- X{
- X char *p = s + strlen(s) - 1;
- X if (!s || !*s)
- X return(1);
- X while (isspace(*s)) s++;
- X if (s == p && *s == '.')
- X return(1);
- X else
- X return(0);
- X}
- X
- Xget_data(this_plot,this_style)
- Xstruct dfile *this_plot;
- Xenum INP_STYLE this_style;
- X{
- X static char data_file[MAX_LINE_LEN+1], line[MAX_LINE_LEN+1];
- X register int i, l_num, ob_num, scanval;
- X register FILE *fp;
- X double x;
- X struct chunk *chn;
- X char *labpt;
- X int chsiz = CH_INIT_SIZE;
- X int lablen, aux;
- X
- X quote_str(data_file, c_token);
- X m_quote_capture(&(this_plot->fname), c_token, c_token);
- X
- X chn = (struct chunk *) alloc((unsigned)sizeof(struct chunk), data_file);
- X chn->next = NULL; /* in case of further errors */
- X chn->dval = NULL;
- X chn->vlbl = (char **) NULL;
- X this_plot->data = chn;
- X this_plot->chunks = 1;
- X if (xmin != -1 && xmax != -1) /* known number of data */
- X chsiz = xmax - xmin + 1;
- X chn->dval = (vreal *) alloc((unsigned)chsiz*sizeof(vreal), data_file);
- X chn->used = 0;
- X if (this_style != CUSTOMD || label_plac.from != -1) { /* labels expected */
- X chn->vlbl = (char **) alloc((unsigned)chsiz*sizeof(char *), data_file);
- X for (i=0; i<chsiz; i++)
- X chn->vlbl[i] = (char *) NULL;
- X }
- X this_plot->d_min = VERYLARGE;
- X this_plot->d_max = -VERYLARGE;
- X this_plot->points = 0;
- X this_plot->makeHL = HL_NON;
- X this_plot->labels = TRUE; /* label autogenerating may be possible */
- X
- X if (!(fp = fopen(data_file, "r")))
- X os_error("can't open data file", c_token);
- X
- X l_num = 0;
- X ob_num = -1; /* will be incremented before any operation */
- X i = -1;
- X
- X while (fgets(line, MAX_LINE_LEN, fp)) { /* REWRITE ALL !!! */
- X l_num++;
- X if (is_comment(line[0]) && this_style != CUSTOMD) /* label can be on any position, incl. 1st column */
- X continue; /* ignore comments */
- X
- X i++;
- X if (i<xmin) continue; /* still out of range */
- X if (xmax != -1 && i>xmax) break; /* don't even read the rest of file */
- X
- X line[strlen(line)-1] = '\0'; /* get rid of '\n' */
- X ob_num++;
- X if (ob_num==chsiz) { /* open new chunk */
- X chn->next = (struct chunk *) alloc((unsigned)sizeof(struct chunk), data_file);
- X chn = chn->next;
- X chn->next = NULL; /* in case of further errors */
- X chn->dval = NULL;
- X chn->vlbl = (char **) NULL;
- X this_plot->chunks++;
- X this_plot->points += chsiz; /* chunkful of points */
- X chsiz *= 2; /* probably the optimal allocation step */
- X chn->dval = (vreal *) alloc((unsigned)chsiz*sizeof(vreal), (char *)NULL);
- X if (!chn->dval)
- X (void) fclose(fp),
- X int_error("out of memory",c_token);
- X chn->used = 0; /* this one */
- X if (this_style != CUSTOMD || label_plac.from != -1) { /* labels expected */
- X chn->vlbl = (char **) alloc((unsigned)chsiz*sizeof(char *), (char *)NULL);
- X if (!chn->vlbl)
- X (void) fclose(fp),
- X int_error("out of memory",c_token++);
- X else {
- X int ii;
- X for (ii=0; ii<chsiz; ii++)
- X chn->vlbl[ii] = (char *) NULL;
- X }
- X }
- X ob_num = 0;
- X }
- X
- X if (!*line && this_style != CUSTOMD) { /* empty data == missing value. not in SAS */
- X chn->dval[ob_num] = VERYLARGE;
- X if (chn->vlbl)
- X chn->vlbl[ob_num] = (char *) NULL;
- X chn->used++;
- X continue;
- X }
- X
- X /* so here we go. now consider input format */
- X switch (this_style) {
- X case PRIVATE:
- X scanval = sscanf(line,"%lf",&x);
- X if (scanval == 1) {
- X for (labpt = line; *labpt && isspace(*labpt); labpt++) ;
- X while (*labpt && !isspace(*labpt)) labpt++;
- X lablen = strlen(labpt); /* initialy */
- X }
- X break;
- X case GNUPLOT:
- X scanval = sscanf(line,"%*lf %lf",&x);
- X if (scanval == 1) {
- X for (aux=0; isspace(line[aux]); aux++);
- X labpt = line + aux;
- X for (lablen=0; !isspace(line[aux++]); lablen++) ;
- X }
- X else labpt=NULL, scanval = sscanf(line,"%lf",&x);
- X break;
- X case CUSTOMD:
- X if (strlen(line) < data_place.from) {
- X scanval = 0; /* generate error */
- X break;
- X }
- X labpt = line + data_place.from;
- X if (data_place.upto == -1 || data_place.upto >= strlen(line))
- X if (missing(labpt))
- X x = VERYLARGE;
- X else
- X scanval = sscanf(labpt,"%lf",&x);
- X else {
- X aux = line[data_place.upto];
- X line[data_place.upto] = '\0';
- X if (missing(labpt))
- X x = VERYLARGE;
- X else
- X scanval = sscanf(labpt,"%lf",&x);
- X line[data_place.upto] = aux;
- X }
- X if (x == VERYLARGE) { /* missing value detected, or unplottable anyway */
- X chn->dval[ob_num] = VERYLARGE;
- X if (chn->vlbl)
- X chn->vlbl[ob_num] = (char *) NULL;
- X chn->used++;
- X continue;
- X }
- X if (label_plac.from >= strlen(line) || label_plac.from == -1)
- X labpt = NULL;
- X else {
- X labpt = line + label_plac.from;
- X if (label_plac.upto == -1 || label_plac.upto >= strlen(line))
- X lablen = strlen(labpt);
- X else
- X lablen = label_plac.upto - label_plac.from - 1;
- X }
- X break;
- X }
- X
- X if (scanval != 1) { /* can be also EOF for empty line */
- X (void) sprintf(line, "bad data on line %d", l_num);
- X (void) fclose(fp);
- X int_error(line,c_token);
- X }
- X
- X if (x<0.0 && data_style == PIECHART ||
- X x<1.0 && data_style != PIECHART && log_y) {
- X (void) fclose(fp);
- X (void) sprintf(line,"unplotable data on line %d",l_num);
- X int_error(line,c_token);
- X }
- X
- X if (log_y) x = log10(x);
- X
- X chn->dval[ob_num] = (vreal) x;
- X if (x<this_plot->d_min) this_plot->d_min = (vreal) x;
- X if (x>this_plot->d_max) this_plot->d_max = (vreal) x; /* without 'else', I know */
- X
- X if (labpt && *labpt && lablen && strunc!=0) { /* copy existing label -- ignore if empty */
- X char *q;
- X /* remove meaningless spaces */
- X while (isspace(*labpt)) labpt++, lablen--;
- X while (isspace(labpt[lablen])) lablen--;
- X if (strunc>0 && strunc<lablen)
- X lablen = strunc;
- X if (!lablen) /* truncated to zero */
- X chn->vlbl[ob_num] = (char *) NULL;
- X else {
- X if (!(q = alloc((unsigned) lablen+1, (char *)NULL))) {
- X (void) fclose(fp);
- X int_error("out of memory",c_token);
- X }
- X (void) strncpy(q,labpt,lablen);
- X q[lablen] = '\0';
- X chn->vlbl[ob_num] = q;
- X this_plot->labels = FALSE; /* cannot autogenerate labels if some exist */
- X }
- X }
- X else
- X chn->vlbl[ob_num] = (char *) NULL;
- X
- X chn->used++;
- X } /* while */
- X
- X (void) fclose(fp);
- X if (i<xmin)
- X int_error("too few data",c_token);
- X
- X this_plot->points += chn->used;
- X
- X}
- X
- Xeval_plots(xplot)
- XBOOLEAN xplot;
- X{
- X struct dfile *dp = &data_head, *tail;
- X enum INP_STYLE in_st;
- X
- X data_head.d_min = VERYLARGE; data_head.d_max = -VERYLARGE;
- X data_head.points = data_head.chunks = 0;
- X if (data_head.data) free((char *)data_head.data);
- X data_head.data = NULL;
- X destroy(data_head.dnxt);
- X data_head.dnxt = (struct dfile *) NULL;
- X data_head.makeHL = HLitem;
- X data_head.labels = auto_label;
- X
- X while (TRUE) {
- X if (END_OF_COMMAND)
- X int_error("data file to plot expected",c_token);
- X if (equals(c_token,"(")) {
- X c_token++;
- X in_st = get_input();
- X if (END_OF_COMMAND || !equals(c_token,")"))
- X int_error("expected ')'",c_token);
- X c_token++;
- X }
- X else
- X in_st = inp_style;
- X if (in_st == CUSTOMD && data_place.from == -1)
- X int_error("Customized input format not defined. Use 'set customized'",NO_CARET);
- X
- X if (END_OF_COMMAND || !isstring(c_token))
- X int_error("data file to plot expected",c_token);
- X tail = (struct dfile *) alloc((unsigned int) sizeof(struct dfile), "data");
- X tail->fname = NULL;
- X tail->data = NULL;
- X tail->dnxt = NULL;
- X dp->dnxt = tail; /* to free all memory on error */
- X
- X get_data(tail,in_st);
- X
- X c_token++;
- X dp = tail;
- X data_head.chunks++; /* here we count overall number of files */
- X if (data_style != ABARS && data_style != PIECHART || xplot) /* if (ABARS || PIECHART => xplot) */
- X data_head.labels = data_head.labels && dp->labels; /* is making labels sensible or not ? */
- X /* else this serves different purpose */
- X if (data_head.points < dp->points)
- X data_head.points = dp->points; /* ... and maximal number of points */
- X if (data_head.d_min > dp->d_min)
- X data_head.d_min = dp->d_min; /* minimum ... */
- X if (data_head.d_max < dp->d_max)
- X data_head.d_max = dp->d_max; /* and maximum */
- X
- X if (almost_equals(c_token,"a$s")) {
- X c_token++;
- X if (END_OF_COMMAND || !isstring(c_token))
- X int_error("name in quotes expected", c_token);
- X else {
- X m_quote_capture(&(dp->fname), c_token, c_token);
- X c_token++;
- X }
- X }
- X
- X if (almost_equals(c_token,"h$ighlighting")) {
- X c_token++;
- X dp->makeHL = get_HL();
- X }
- X
- X if (END_OF_COMMAND)
- X break;
- X else if (equals(c_token,","))
- X c_token++;
- X else
- X int_error("expected ','",c_token);
- X }
- X
- X if (data_head.d_min == VERYLARGE || data_head.d_max == -VERYLARGE)
- X int_error("all points undefined, nothing to draw",NO_CARET);
- X
- X if (data_head.chunks > 1) { /* reserve space for xpointers structure */
- X /* do it here, to avoid memory management in graphics.c */
- X data_head.data = (struct chunk *) alloc((unsigned)data_head.chunks*sizeof(struct xptr), "data");
- X }
- X
- X capture(replot_line,plot_token,c_token);
- X do_plot(xplot,data_style,xmin<=0?0:xmin);
- X}
- X
- Xdone(status)
- Xint status;
- X{
- X if (term && term_init)
- X (*term_tbl[term].reset)();
- X#ifdef VMS
- X vms_reset();
- X#endif
- X exit(status);
- X}
- X
- X#ifdef MSDOS
- X#ifndef __TURBOC__ /* Turbo C already has sleep() */
- X#ifndef __ZTC__ /* ZTC already has usleep() */
- X/* kludge to provide sleep() for msc 5.1 */
- Xvoid sleep(delay)
- Xunsigned int delay;
- X{
- Xunsigned long time_is_up;
- X time_is_up = time(NULL) + (unsigned long) delay;
- X while (time(NULL)<time_is_up)
- X /* wait */ ;
- X}
- X#endif /* not ZTC */
- X#endif /* not TURBOC */
- X#endif /* MSDOS */
- X
- X
- X/* Support for input, shell, and help for various systems */
- X
- X#ifdef vms
- X
- X#include <descrip.h>
- X#include <rmsdef.h>
- X#include <errno.h>
- X
- Xextern lib$get_input(), lib$put_output();
- X
- Xint vms_len;
- X
- Xunsigned int status[2] = {1, 0};
- X
- Xstatic char help[MAX_LINE_LEN+1] = "fchart";
- X
- X$DESCRIPTOR(prompt_desc,PROMPT);
- X$DESCRIPTOR(line_desc,input_line);
- X
- X$DESCRIPTOR(help_desc,help);
- X$DESCRIPTOR(helpfile_desc,"FCHART$HELP");
- X
- Xread_line(prompt)
- Xchar *prompt;
- X{
- X int more, start=0;
- X char exp_prompt = EXP_PROMPT;
- X prompt_desc.dsc$w_length = strlen (prompt);
- X prompt_desc.dsc$a_pointer = prompt;
- X do {
- X line_desc.dsc$w_length = MAX_LINE_LEN - start;
- X line_desc.dsc$a_pointer = &input_line[start];
- X switch(status[1] = lib$get_input(&line_desc, &prompt_desc, &vms_len)){
- X case RMS$_EOF:
- X done(IO_SUCCESS); /* ^Z isn't really an error */
- X break;
- X case RMS$_TNS: /* didn't press return in time */
- X vms_len--; /* skip the last character */
- X break; /* and parse anyway */
- X case RMS$_BES: /* Bad Escape Sequence */
- X case RMS$_PES: /* Partial Escape Sequence */
- X sys$putmsg(status);
- X vms_len = 0; /* ignore the line */
- X break;
- X case SS$_NORMAL:
- X break; /* everything's fine */
- X default:
- X done(status[1]); /* give the error message */
- X }
- X start += vms_len;
- X input_line[start] = '\0';
- X if (input_line[start-1] == '\\') {
- X /* Allow for a continuation line. */
- X prompt_desc.dsc$w_length = strlen (exp_prompt);
- X prompt_desc.dsc$a_pointer = exp_prompt;
- X more = 1;
- X --start;
- X }
- X else {
- X line_desc.dsc$w_length = strlen(input_line);
- X line_desc.dsc$a_pointer = input_line;
- X more = 0;
- X }
- X } while (more);
- X}
- X
- X
- Xdo_help()
- X{
- X help_desc.dsc$w_length = strlen(help);
- X if ((vaxc$errno = lbr$output_help(lib$put_output,0,&help_desc,
- X &helpfile_desc,0,lib$get_input)) != SS$_NORMAL)
- X os_error("can't open FCHART$HELP");
- X}
- X
- X
- Xdo_shell()
- X{
- X if ((vaxc$errno = lib$spawn()) != SS$_NORMAL) {
- X os_error("spawn error",NO_CARET);
- X }
- X}
- X
- X
- Xdo_system()
- X{
- X input_line[0] = ' '; /* an embarrassment, but... */
- X
- X if ((vaxc$errno = lib$spawn(&line_desc)) != SS$_NORMAL)
- X os_error("spawn error",NO_CARET);
- X
- X (void) putc('\n',stderr);
- X}
- X
- X#else /* vms */
- X
- X/* do_help: (not VMS, although it would work)
- X * Give help to the user.
- X * It parses the command line into helpbuf and supplies help for that
- X * string. Then, if there are subtopics available for that key,
- X * it prompts the user with this string. If more input is
- X * given, do_help is called recursively, with the argument the index of
- X * null character in the string. Thus a more specific help can be
- X * supplied. This can be done repeatedly.
- X * If null input is given, the function returns, effecting a
- X * backward climb up the tree.
- X * David Kotz (dfk@cs.duke.edu) 10/89
- X */
- Xdo_help()
- X{
- X static char helpbuf[MAX_LINE_LEN] = "";
- X static char prompt[MAX_LINE_LEN] = "";
- X int base; /* index of first char AFTER help string */
- X int len; /* length of current help string */
- X BOOLEAN more_help;
- X BOOLEAN only; /* TRUE if only printing subtopics */
- X int subtopics; /* 0 if no subtopics for this topic */
- X int start; /* starting token of help string */
- X char *help_ptr; /* name of help file */
- X
- X if ( (help_ptr = getenv("FCHARTHELP")) == (char *)NULL )
- X /* if can't find environment variable then just use HELPFILE */
- X help_ptr = HELPFILE;
- X
- X len = base = strlen(helpbuf);
- X
- X /* find the end of the help command */
- X for (start = c_token; !(END_OF_COMMAND); c_token++) ;
- X /* copy new help input into helpbuf */
- X if (len > 0)
- X helpbuf[len++] = ' '; /* add a space */
- X capture(helpbuf+len, start, c_token-1);
- X squash_spaces(helpbuf+base); /* only bother with new stuff */
- X lower_case(helpbuf+base); /* only bother with new stuff */
- X len = strlen(helpbuf);
- X
- X /* now, a lone ? will print subtopics only */
- X if (strcmp(helpbuf + (base ? base+1 : 0), "?") == 0) {
- X /* subtopics only */
- X subtopics = 1;
- X only = TRUE;
- X helpbuf[base] = '\0'; /* cut off question mark */
- X } else {
- X /* normal help request */
- X subtopics = 0;
- X only = FALSE;
- X }
- X
- X switch ( help(helpbuf, help_ptr, &subtopics)) {
- X case H_FOUND: {
- X /* already printed the help info */
- X /* subtopics now is true if there were any subtopics */
- X screen_ok = FALSE;
- X
- X do {
- X if (subtopics && !only) {
- X /* prompt for subtopic with current help string */
- X if (len > 0)
- X (void) sprintf(prompt, "Subtopic of %s: ", helpbuf);
- X else
- X (void) strcpy(prompt, "Help topic: ");
- X read_line(prompt);
- X num_tokens = scanner(input_line);
- X c_token = 0;
- X more_help = !(END_OF_COMMAND);
- X if (more_help)
- X /* base for next level is all of current helpbuf */
- X do_help();
- X } else
- X more_help = FALSE;
- X } while(more_help);
- X
- X break;
- X }
- X case H_NOTFOUND: {
- X printf("Sorry, no help for '%s'\n", helpbuf);
- X break;
- X }
- X case H_ERROR: {
- X perror(help_ptr);
- X break;
- X }
- X default: { /* defensive programming */
- X int_error("Impossible case in switch\n", NO_CARET);
- X /* NOTREACHED */
- X }
- X }
- X
- X helpbuf[base] = '\0'; /* cut it off where we started */
- X}
- X
- Xdo_system()
- X{
- X if (system(input_line + 1))
- X os_error("system() failed",NO_CARET);
- X}
- X
- X#ifdef MSDOS
- X
- Xread_line(prompt)
- Xchar *prompt;
- X{
- X int last, start = 0;
- X BOOLEAN more;
- X
- X#ifndef __ZTC__
- X if (interactive) { /* if interactive use console IO so CED will work */
- X cputs(prompt);
- X do {
- X input_line[start] = MAX_LINE_LEN - start - 1;
- X cgets(&(input_line[start]));
- X (void) putc('\n',stderr);
- X if (input_line[start+2] == 26) {
- X /* end-of-file */
- X (void) putc('\n',stderr);
- X input_line[start] = '\0';
- X if (start > 0) /* don't quit yet - process what we have */
- X more = FALSE;
- X else {
- X (void) putc('\n',stderr);
- X done(IO_SUCCESS);
- X /* NOTREACHED */
- X }
- X } else {
- X /* normal line input */
- X register i = start;
- X while ( (input_line[i] = input_line[i+2]) != (char)NULL )
- X i++; /* yuck! move everything down two characters */
- X
- X last = strlen(input_line) - 1;
- X if (last + 1 >= MAX_LINE_LEN)
- X int_error("Input line too long",NO_CARET);
- X
- X if (input_line[last] == '\\') { /* line continuation */
- X start = last;
- X more = TRUE;
- X } else
- X more = FALSE;
- X }
- X if (more && isatty(fileno(stdin)))
- X cputs(EXP_PROMPT);
- X } while(more);
- X }
- X else { /* not interactive */
- X#endif /* not ZTC */
- X if (interactive)
- X fputs(prompt,stderr);
- X do {
- X /* grab some input */
- X if ( fgets(&(input_line[start]), MAX_LINE_LEN - start, stdin)
- X == (char *)NULL ) {
- X /* end-of-file */
- X if (interactive)
- X (void) putc('\n',stderr);
- X input_line[start] = '\0';
- X if (start > 0) /* don't quit yet - process what we have */
- X more = FALSE;
- X else
- X done(IO_SUCCESS); /* no return */
- X } else {
- X /* normal line input */
- X last = strlen(input_line) - 1;
- X if (input_line[last] == '\n') { /* remove any newline */
- X input_line[last] = '\0';
- X /* Watch out that we don't backup beyond 0 (1-1-1) */
- X if (last > 0) --last;
- X } else if (last+1 >= MAX_LINE_LEN)
- X int_error("Input line too long",NO_CARET);
- X
- X if (input_line[last] == '\\') { /* line continuation */
- X start = last;
- X more = TRUE;
- X } else
- X more = FALSE;
- X }
- X if (more && interactive)
- X fputs(EXP_PROMPT, stderr);
- X } while(more);
- X#ifndef __ZTC
- X }
- X#endif
- X
- X#ifdef FILIP
- X input_line[0] = MAX_LINE_LEN - 1;
- X cputs(PROMPT);
- X cgets(input_line); /* console input so CED will work */
- X (void) putc('\n',stderr);
- X if (input_line[2] == 26) {
- X (void) putc('\n',stderr); /* end-of-file */
- X done(IO_SUCCESS);
- X }
- X
- X i = 0;
- X while (input_line[i] = input_line[i+2])
- X i++; /* yuck! move everything down two characters */
- X#endif
- X}
- X
- X
- Xdo_shell()
- X{
- X register char *comspec;
- X if (!(comspec = getenv("COMSPEC")))
- X comspec = "\command.com";
- X if (spawnl(P_WAIT,comspec,NULL) == -1)
- X os_error("unable to spawn shell",NO_CARET);
- X}
- X
- X#else /* MSDOS */
- X/* plain old Unix */
- X
- Xread_line(prompt)
- Xchar *prompt;
- X{
- X int start=0, last=0;
- X BOOLEAN more;
- X
- X if (interactive) fputs(prompt,stderr);
- X do {
- X if (!fgets(&input_line[start], MAX_LINE_LEN-start, stdin)) {
- X if (interactive)
- X (void) putc('\n',stderr); /* end-of-file */
- X input_line[start] = '\0';
- X if (start > 0) /* don't quit yet - process what we have */
- X more = FALSE;
- X else
- X done(IO_SUCCESS); /* no return */
- X }
- X else { /* normal line input */
- X last = strlen(input_line)-1;
- X if (input_line[last] == '\n') { /* remove any newline */
- X input_line[last] = '\0';
- X /* Watch out that we don't backup beyond 0 (1-1-1) */
- X if (last > 0) --last;
- X }
- X else if (last+1 >= MAX_LINE_LEN)
- X int_error("Input line too long",NO_CARET);
- X
- X if (input_line[last] == '\\') { /* line continuation */
- X start = last;
- X more = TRUE;
- X } else
- X more = FALSE;
- X }
- X if (more && interactive) fputs(EXP_PROMPT,stderr);
- X } while (more);
- X}
- X
- X#ifdef VFORK
- X
- Xdo_shell()
- X{
- Xregister char *shell;
- Xregister int p;
- Xstatic int execstat;
- X if (!(shell = getenv("SHELL")))
- X shell = SHELL;
- X if ((p = vfork()) == 0) {
- X execstat = execl(shell,shell,NULL);
- X _exit(1);
- X } else if (p == -1)
- X os_error("vfork failed",c_token);
- X else
- X while (wait(NULL) != p)
- X ;
- X if (execstat == -1)
- X os_error("shell exec failed",c_token);
- X (void) putc('\n',stderr);
- X}
- X#else /* VFORK */
- X
- X#define EXEC "exec "
- Xdo_shell()
- X{
- Xstatic char exec[100] = EXEC;
- Xregister char *shell;
- X if (!(shell = getenv("SHELL")))
- X shell = SHELL;
- X
- X if (system(strncpy(&exec[sizeof(EXEC)-1],shell,
- X sizeof(exec)-sizeof(EXEC)-1)))
- X os_error("system() failed",NO_CARET);
- X
- X (void) putc('\n',stderr);
- X}
- X#endif /* VFORK */
- X#endif /* MSDOS */
- X#endif /* vms */
- SHAR_EOF
- $TOUCH -am 0604152590 fcmd.c &&
- chmod 0666 fcmd.c ||
- echo "restore of fcmd.c failed"
- set `wc -c fcmd.c`;Wc_c=$1
- if test "$Wc_c" != "45623"; then
- echo original size 45623, current size $Wc_c
- fi
- # ============= fgraf.c ==============
- echo "x - extracting fgraf.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > fgraf.c &&
- X/*
- X *
- X * Fchart -- fgraf.c
- X *
- X * Copyright (C) 1990 Piotr Filip Sawicki
- X *
- X * WARNING:
- X * Included "fstyles.i" is an older version of already rewritten graphics
- X * module. Please, don't change anything, rather mail me suggestions.
- X * It emerged like a ball of mud -- don't be shocked with this code.
- X * Writing program I jjust have been adding here new styles, parameters,
- X * bells and whistles -- so it looks like it looks.
- X *
- X * Rest of the code can be freely modified and used, as long as this message
- X * is retained and modified code is not redistributed.
- X *
- X * Please e-mail any useful additions to fs@uwasa.fi so they may be
- X * included in later releases.
- X *
- X * This file should be edited with 4-column tabs! (:set ts=4 sw=4 in vi)
- X */
- X
- X#include <stdio.h>
- X#include <math.h>
- X#include "plot.h"
- X#include "fchart.h"
- X
- X/***********************************************************************/
- X
- X#define MARGIN 0.95 /* margin within frame */
- X
- X/***********************************************************************/
- X
- X
- Xchar *strcpy(),*strncpy(),*strcat(),*sprintf(); /* for lint only */
- X
- Xchar *make_labl();
- X
- Xextern BOOLEAN autoscale;
- Xextern FILE *outfile;
- Xextern BOOLEAN log_y;
- Xextern int term;
- Xextern BOOLEAN draw_border;
- X
- Xextern BOOLEAN screen_ok;
- Xextern BOOLEAN term_init;
- X
- Xextern double loff,roff,toff,boff;
- Xextern double zero;
- X
- Xextern enum GRAV_DIR gravity, explode;
- Xextern int samples;
- Xextern double base;
- Xextern BOOLEAN p_clockwise, b_clockwise;
- Xextern double radexp, treshold;
- Xextern double b_wid, b_spc, b_int;
- Xextern char thrname[];
- X
- Xextern float xsize, ysize;
- X
- Xextern char tic_form[];
- X
- Xextern enum FONT_STYLE vect_font;
- X
- Xextern struct termentry term_tbl[];
- Xextern struct dfile data_head; /* static head of data list */
- X
- Xextern struct label_def *first_label; /* defined in flblarr.c */
- Xextern struct linearrow_def *first_arrow; /* defined in flblarr.c */
- X
- X#ifndef toascii
- X#define toascii(A) (((int)(A)) & 0x7F)
- X#endif
- X
- X#define SIGN(A) (A>=0 ? 1 : -1)
- X
- Xextern struct Char trt[]; /* font translation table */
- X
- Xstatic struct termentry *t; /* faster */
- Xstatic int xbase, ybase, xmaxp, ymaxp; /* viewport */
- Xstatic struct xptr *across; /* used for xplot */
- Xstatic int first_element; /* first element for autolabeling */
- Xstatic BOOLEAN trotate; /* whether terminal can rotate text or not */
- Xstatic int tstate; /* state of terminal text rotation */
- Xstatic int howmuch; /* how much space takes as text the longest used value */
- X
- Xdo_plot(xplot,style,fel)
- XBOOLEAN xplot;
- Xenum DRAW_STYLE style;
- Xint fel;
- X{
- X /**This bloody part of code initializes graphic *
- X * environment, draws borders, outputs trailer, *
- X * etc. Before calling drawing fuctions it cal- *
- X * culates viewport (see toff,boff,roff,loff) *
- X * and some other variables used in any style. *
- X * Ough, how I long to Pascal's nested local *
- X * procedures !!! */
- X
- X BOOLEAN dolabel = (data_head.fname != (char *)NULL);
- X int effect, x, y, x0, dx, y0, dy;
- X struct label_def *lb;
- X struct linearrow_def *ar;
- X
- X t = &term_tbl[term];
- X if (!(*t->scale)(xsize, ysize)) {
- X x = t->xmax * xsize;
- X y = t->ymax * ysize;
- X }
- X else {
- X x = t->xmax;
- X y = t->ymax;
- X }
- X
- X y0 = ybase = (int) ((boff>1.0 ? boff/100.0 : boff)*y) + 1;
- X dy = ymaxp = (int) ((1.0-(toff>1.0 ? toff/100.0 : toff))*(y-2)) - (dolabel ? 3*t->v_char : 0);
- X if (ymaxp <= ybase)
- X int_error("no space to put title, change offsets", NO_CARET);
- X x0 = xbase = (int) ((loff>1.0 ? loff/100.0 : loff)*x) + 1;
- X dx = xmaxp = (int) ((1.0-(roff>1.0 ? roff/100.0 : roff))*(x-2));
- X
- X across = (struct xptr *) data_head.data;
- X first_element = fel;
- X
- X if (!term_init) {
- X (*t->init)();
- X term_init = TRUE;
- X }
- X screen_ok = FALSE;
- X (*t->graphics)();
- X trotate = (*t->text_angle)(0); /* mostly harmless */
- X tstate = 0;
- X
- X switch (style) {
- X case ABARS : effect = dr_abar(xplot);
- X break;
- X case SBAR : effect = dr_sbar(xplot);
- X break;
- X case LAYB : effect = dr_lbar(xplot);
- X break;
- X case PIECHART : effect = dr_pies(xplot);
- X break;
- X default :
- X (*t->text)();
- X (void) fflush(outfile);
- X int_error("style not yet implemented",NO_CARET);
- X }
- X
- X if (!effect) {
- X (*t->text)();
- X (void) fflush(outfile);
- X int_error("too many data to make sensible picture", NO_CARET);
- X }
- X
- X (*t->linetype)(-2); /* border linetype */
- X if (draw_border) { /* draw plot border */
- X (*t->move)(0,0);
- X (*t->vector)(x-1,0);
- X (*t->vector)(x-1,y-1);
- X (*t->vector)(0,y-1);
- X (*t->vector)(0,0);
- X }
- X
- X (*t->linetype)(0); /* only one guaranted to be solid */
- X if (dolabel) /* put title */
- X put_txt((x0+dx)/2, (int)(dy+3*t->v_char/2), data_head.fname, CENTRE, 0);
- X
- X for (lb=first_label; lb; lb=lb->next) { /* process and put labels */
- X double c_x = lb->x <= 1.0 ? lb->x : lb->x/RESOLUTION;
- X double c_y = lb->y <= 1.0 ? lb->y : lb->y/RESOLUTION;
- X double c_h = lb->h <= 1.0 ? lb->h : lb->h/RESOLUTION;
- X double c_w = lb->w <= 1.0 ? lb->w : lb->w/RESOLUTION;
- X int lx, ly, r_x, r_y, r0x, r0y;
- X if (!*lb->text)
- X continue;
- X
- X if (lb->paged) {
- X r0x = r0y = 0;
- X r_x = x; r_y = y;
- X }
- X else {
- X r0x = x0; r0y = y0;
- X r_x = dx-x0; r_y = dy-y0;
- X }
- X lx = r0x + c_x*r_x;
- X ly = r0y + c_y*r_y;
- X
- X if ((lb->rot == L_NORMAL || lb->rot == L_BOTTOM) &&
- X !lb->h && !lb->w) /* try to put it as a normal text */
- X put_txt(lx, ly, lb->text, lb->pos, lb->rot==L_NORMAL ? 0 : 1);
- X else {
- X double an = (int)lb->rot * Pi/2;
- X if (!lb->h && !lb->w) /* use standard size */
- X (void) draw_text(lx, ly, lb->text, (int)t->v_char, 0, -1, lb->pos, lb->rot==L_RANDOM ? lb->a : an);
- X else /* draw_text will worry */
- X (void) draw_text(lx, ly, lb->text, (int)(c_h*r_y), (int)(c_w*r_x),
- X -1, lb->pos, lb->rot==L_RANDOM ? lb->a : an);
- X }
- X }
- X
- X for (ar=first_arrow; ar; ar=ar->next) { /* process and put arrows/lines */
- X double c_sx = ar->sx <= 1.0 ? ar->sx : ar->sx/RESOLUTION;
- X double c_sy = ar->sy <= 1.0 ? ar->sy : ar->sy/RESOLUTION;
- X double c_ex = ar->ex <= 1.0 ? ar->ex : ar->ex/RESOLUTION;
- X double c_ey = ar->ey <= 1.0 ? ar->ey : ar->ey/RESOLUTION;
- X int sx,sy,ex,ey;
- X if (ar->startp) {
- X sx = x*c_sx;
- X sy = y*c_sy;
- X }
- X else {
- X sx = x0 + (dx-x0)*c_sx;
- X sy = y0 + (dy-y0)*c_sy;
- X }
- X if (ar->endp) {
- X ex = x*c_ex;
- X ey = y*c_ey;
- X }
- X else {
- X ex = x0 + (dx-x0)*c_ex;
- X ey = y0 + (dy-y0)*c_ey;
- X }
- X
- X if (ar->arrow)
- X (*t->arrow)(sx, sy, ex, ey);
- X else {
- X (*t->move)(sx, sy);
- X (*t->vector)(ex, ey);
- X }
- X }
- X
- X (*t->text)();
- X (void) fflush(outfile);
- X}
- X
- X#define MCx(PT,R,AN) nint((PT)+(R)*cos(AN))
- X#define MCy(PT,R,AN) nint((PT)+(R)*sin(AN))
- X
- Xput_arc(x,y,r,a0,da)
- Xint x,y,r;
- Xdouble a0,da;
- X/* draw arc from a0, da long */
- X{
- X double step, drto;
- X int iter;
- X
- X (*t->move)(MCx(x,r,a0),MCy(y,r,a0));
- X step = 2*Pi/samples * (da>0.0 ? 1 : -1); /* angle step */
- X iter = nint(floor(da/step)); /* number of iterations - makes loop faster */
- X drto = a0 + step; /* next place to draw */
- X while (iter--) {
- X (*t->vector)(MCx(x,r,drto),MCy(y,r,drto));
- X drto += step;
- X }
- X (*t->vector)(MCx(x,r,a0+da),MCy(y,r,a0+da)); /* last part - prob. shorter */
- X}
- X
- Xput_bar(x0,y0,dx,dy,turn)
- Xint x0,y0,dx,dy,turn;
- X/* put single bar (opened rectangle) */
- X{
- X if (turn) (*t->move)(x0,y0+dy);
- X else {
- X (*t->move)(x0,y0);
- X (*t->vector)(x0,y0+dy);
- X }
- X (*t->vector)(x0+dx,y0+dy);
- X (*t->vector)(x0+dx,y0);
- X if (turn)
- X (*t->vector)(x0,y0);
- X}
- X
- XBOOLEAN find_ran(min, max, sum, lab)
- Xdouble *min, *max, *sum;
- Xchar **lab; /* NULL if all labels undefined; "" if labels different; else pointer to the good label */
- X/**find function used for stacked bars: find min, max and total sum across all data. *
- X * Check also possibility of labelling across etc. */
- X{
- X int i;
- X vreal w;
- X static char nothing[] = "";
- X int labfound = 1;
- X char *good = NULL, *aux;
- X
- X *min = VERYLARGE;
- X *max = -VERYLARGE;
- X *sum = 0.0;
- X for (i=0; i<data_head.chunks; i++) {
- X if (!across[i].chnp || (w=across[i].chnp->dval[across[i].vindex]) == VERYLARGE) continue;
- X if (*min > w) *min = w;
- X if (*max < w) *max = w;
- X *sum += w;
- X if (labfound && across[i].chnp->vlbl && (aux = across[i].chnp->vlbl[across[i].vindex]))
- X if (!good) /* first found */
- X good = aux;
- X else
- X labfound = !strcmp(good,aux);
- X }
- X
- X if (!good) /* no label found, all undefined */
- X *lab = NULL;
- X else if (labfound) /* all labels are the same -- return any */
- X *lab = good;
- X else /* different -- return fake label (will be processed in function, but rejected later) */
- X *lab = nothing;
- X
- X if (*min == VERYLARGE || *max == -VERYLARGE) /* all points undefined */
- X return(FALSE);
- X else
- X return(TRUE);
- X}
- X
- Xchar *comm_lget()
- X/* check labels (like find_ran above), but also advance pointers */
- X{
- X int i, j;
- X static char nothing[] = "";
- X int labfound = 1;
- X char *good = NULL, *aux;
- X
- X for (i=0; i<data_head.chunks; i++) {
- X if (!across[i].chnp) continue;
- X j = across[i].vindex;
- X if (across[i].chnp->dval[j] != VERYLARGE && across[i].chnp->vlbl && (aux = across[i].chnp->vlbl[j]))
- X if (!good) /* first found */
- X good = aux;
- X else
- X labfound = !strcmp(good,aux);
- X if (++across[i].vindex == across[i].chnp->used) {
- X across[i].chnp = across[i].chnp->next;
- X across[i].vindex = 0;
- X }
- X }
- X
- X if (!good) /* no label found, all undefined */
- X return (NULL);
- X else if (labfound) /* all labels are the same -- return any */
- X return (good);
- X else
- X return (nothing);
- X}
- X
- Xdo_axis(a1,a2,xb,xm,yb,ym,reserved)
- Xdouble *a1, *a2;
- Xint xb, xm, yb, ym;
- XBOOLEAN reserved; /* should we shrink drawing area, or there's enough space ? */
- X/* draws axis for bars, reserve space for values, put tickmarks with labels */
- X{
- X double minv = *a1, maxv = *a2, tick, minpl, maxpl, unit;
- X int dirNS = !((int)gravity&1);
- X int i, j, space;
- X
- X space = dirNS ? (ym-yb)/t->v_char : (xm-xb)/t->h_char;
- X if (minv == maxv)
- X tick=0;
- X else if (log_y) {
- X minpl = minv = floor(minv)+log10(2.0)<minv ? floor(minv)+log10(2.0) : floor(minv);
- X maxpl = maxv = ceil(maxv)-log10(2.0)>maxv ? ceil(maxv)-log10(2.0) : ceil(maxv);
- X tick = floor(log10(maxv-minv))+1;
- X }
- X else {
- X double aux = fabs(minv)>fabs(maxv) ? fabs(minv) : fabs(maxv);
- X tick = exp10(floor(log10(aux)));
- X aux = exp10(floor(log10(aux)-1));
- X minpl = tick * ceil(minv/tick);
- X maxpl = tick * floor(maxv/tick);
- X minv = aux * floor(minv/aux);
- X maxv = aux * ceil(maxv/aux);
- X if ((maxv-minv)/tick <= 3.0) {
- X int flip = 1;
- X do {
- X tick /= flip ? 2.0 : 5.0;
- X flip = 1-flip;
- X minpl = tick * ceil(minv/tick);
- X maxpl = tick * floor(maxv/tick);
- X } while ((maxv-minv)/tick <= 3.0);
- X }
- X if ((maxpl-minpl)/tick >= (double)space) {
- X int flip = 1;
- X do {
- X tick *= flip ? 5.0 : 2.0;
- X flip = 1-flip;
- X minpl = tick * ceil(minv/tick);
- X maxpl = tick * floor(maxv/tick);
- X } while ((maxpl-minpl)/tick >= (double)space);
- X }
- X }
- X
- X if (!tick) return(0);
- X
- X unit = (dirNS ? ym-yb : xm-xb)/(maxv-minv);
- X (*t->linetype)(0); /* solid linetype */
- X switch (gravity) {
- X case SOUTH:
- X if (!reserved)
- X xb += t->h_char*howmuch + 2*t->h_tic;
- X j = xb - 2*t->h_tic;
- X (*t->move)(xb,yb);
- X (*t->vector)(xb,ym);
- X (*t->linetype)(0); /* the only type solid for sure */
- X while (minpl<=maxpl) {
- X (*t->move)(xb,i=yb+nint((minpl-minv)*unit));
- X (*t->vector)(xb-t->h_tic,i);
- X put_txt(j, i, make_labl((double) (log_y ? exp10(minpl) : minpl)), RIGHT, 0);
- X minpl += tick;
- X }
- X break;
- X case NORTH:
- X if (!reserved)
- X xm -= t->h_char*howmuch + 2*t->h_tic;
- X j = xm + 2*t->h_tic;
- X (*t->move)(xm,yb);
- X (*t->vector)(xm,ym);
- X (*t->linetype)(0); /* the only type solid for sure */
- X while (minpl<=maxpl) {
- X (*t->move)(xm,i=ym-nint((minpl-minv)*unit));
- X (*t->vector)(xm+t->h_tic,i);
- X put_txt(j, i, make_labl((double) (log_y ? exp10(minpl) : minpl)), LEFT, 0);
- X minpl += tick;
- X }
- X break;
- X case WEST:
- X if (!reserved)
- X ym -= t->v_char*howmuch + 2*t->v_tic;
- X j = ym + 2*t->v_tic;
- X (*t->move)(xb,ym);
- X (*t->vector)(xm,ym);
- X (*t->linetype)(0); /* the only type solid for sure */
- X while (minpl<=maxpl) {
- X (*t->move)(i=xb+nint((minpl-minv)*unit),ym);
- X (*t->vector)(i,ym+t->v_tic);
- X put_txt(i, j, make_labl((double) (log_y ? exp10(minpl) : minpl)), LEFT, 1);
- X minpl += tick;
- X }
- X break;
- X case EAST:
- X if (!reserved)
- X yb += t->v_char*howmuch + 2*t->v_tic;
- X j = yb - 2*t->v_tic;
- X (*t->move)(xm,yb);
- X (*t->vector)(xb,yb);
- X (*t->linetype)(0); /* the only type solid for sure */
- X while (minpl<=maxpl) {
- X (*t->move)(i=xm-nint((minpl-minv)*unit),yb);
- X (*t->vector)(i,yb-t->v_tic);
- X put_txt(i, j, make_labl((double) (log_y ? exp10(minpl) : minpl)), RIGHT, 1);
- X minpl += tick;
- X }
- X break;
- X }
- X
- X *a1 = minv; *a2 = maxv;
- X return ( (int) (2*(dirNS ? t->h_tic : t->v_tic) + howmuch*(dirNS ? t->h_char : t->v_char)) );
- X /* if (reserved), return value is rejected, so it doesn't matter */
- X}
- X
- X/* from hereon go different labeling functions. The basic one is the first */
- X
- Xint draw_text(x, y, s, h, w, tc, just, an)
- Xint x, y, h, w, tc;
- Xchar *s;
- Xenum JUSTIFY just;
- Xdouble an;
- X/* draw text in vector font and return useful info - complementary of h parameter */
- X{
- X int wid, k, retv, rwid;
- X char *p;
- X double sc;
- X int *d;
- X MATRIX R, S, A;
- X
- X if (!s || !*s || !tc || !h && !w)
- X return(0); /* nothing useful can be done */
- X if (tc>0 && tc < strlen(s))
- X s[tc] = '\0'; /* truncate */
- X
- X for (p=s, wid=0; *p; p++)
- X if (!trt[*p=toascii(*p)].wid)
- X wid += trt[0].wid + CHAR_OFF;
- X else
- X wid += trt[*p].wid + CHAR_OFF;
- X rwid = wid;
- X
- X rotat(-an, R); /* rotate object system (!) */
- X
- X if (h) {
- X sc = (double)(h) / (double)CHAR_GRD;
- X wid *= sc;
- X retv = wid;
- X }
- X else
- X wid = 0;
- X if (!wid || w && wid > w) { /* can't with with desired height -- try to schrink */
- X sc = (double)(w)/(double)(rwid);
- X wid = w;
- X retv = CHAR_GRD*sc; /* return text height */
- X }
- X scale(sc, sc, S);
- X multi(S, R, A);
- X
- X switch (just) {
- X case LEFT: break;
- X case CENTRE: {
- X wid /= 2; /* and no break */
- X }
- X case RIGHT: {
- X x -= (double)wid*cos(an); /* rotate within coordinate system */
- X y -= (double)wid*sin(an);
- X }
- X }
- X if (x<0 || y<0)
- X return(0); /* nothing useful - failed */
- X
- X#ifdef NO_ROMAN_FONT
- X
- X x += (CHAR_OFF/2)*A[0][0]+A[0][2];
- X y += (CHAR_OFF/2)*A[1][0]+A[1][2];
- X
- X#define MX(v) nint( (*(v))*A[0][0] + (*(v+1))*A[0][1] + A[0][2] )
- X#define MY(v) nint( (*(v))*A[1][0] + (*(v+1))*A[1][1] + A[1][2] )
- X
- X {
- X unsigned char *u;
- X int i,j;
- X for ( ; *s; wid=trt[*s].wid, x+=(wid+CHAR_OFF)*A[0][0]+A[0][2], y+=(wid+CHAR_OFF)*A[1][0]+A[1][2], s++) {
- X if (!trt[c=*s].wid) c='\0';
- X for (i=0; i<3 && (u=trt[c].def[i]); i++) {
- X (*t->move) (x+MX(u), y+MY(u));
- X while (*(u+=2))
- X (*t->vector) (x+MX(u), y+MY(u));
- X }
- X }
- X }
- X
- X#undef MX
- X#undef MY
- X
- X#else /* another algorithm: for roman font */
- X
- X x -= (CHAR_OFF/2)*A[0][0]+A[0][2];
- X y -= (CHAR_OFF/2)*A[1][0]+A[1][2];
- X
- X#define MX(v) nint( ((v)/100)*A[0][0] + ((v)%100)*A[0][1] + A[0][2] )
- X#define MY(v) nint( ((v)/100)*A[1][0] + ((v)%100)*A[1][1] + A[1][2] )
- X
- X for ( ; *s; wid=trt[*s].wid, x+=(wid+CHAR_OFF)*A[0][0]+A[0][2], y+=(wid+CHAR_OFF)*A[1][0]+A[1][2], s++)
- X for (d=trt[*s].def; *d; d++)
- X if ((k=*d)<0) {
- X k = abs(k);
- X (*t->move)(x+MX(k), y+MY(k));
- X }
- X else
- X (*t->vector)(x+MX(k), y+MY(k));
- X
- X#undef MX
- X#undef MY
- X
- X#endif
- X
- X return(retv);
- X}
- X
- Xmake_just(x, y, j, l, d)
- Xint *x, *y;
- Xint l, d; /* l != 0 */
- Xenum JUSTIFY j;
- X/* set terminal justification */
- X{
- X if (!d) {
- X if (j == LEFT)
- X (void) (*t->justify_text)(LEFT);
- X else if ((*t->justify_text)(j)) ;
- X else if (j == CENTRE)
- X *x -= t->h_char * l/2;
- X else if (j == RIGHT)
- X *x -= t->h_char * l;
- X else /* impossible */ return;
- X }
- X else {
- X if (j == LEFT)
- X (void) (*t->justify_text)(LEFT);
- X else if ((*t->justify_text)(j)) ;
- X else if (j == CENTRE)
- X *y -= t->h_char * l/2;
- X else if (j == RIGHT)
- X *y -= t->h_char * l;
- X else /* impossible */ return;
- X }
- X}
- X
- Xput_txt(x,y,s,j,d)
- Xint x, y, d;
- Xchar *s;
- Xenum JUSTIFY j;
- X/* put any text on given position, with standard size, sideways or rotated +Pi/2 */
- X{
- X if (!s || !*s) return;
- X if ((trotate || !d) && vect_font == F_WHENN || /* terminal can or need not rotate */
- X vect_font == F_NEVER) { /* never use vector font, regardles of anything */
- X if (tstate != d)
- X (*t->text_angle)(tstate = d);
- X make_just(&x, &y, j, strlen(s), d);
- X (*t->put_text)(x, y, s);
- X }
- X else { /* use vector font */
- X int i = t->v_char;
- X if (d)
- X x += t->h_char/2; /* draw_text takes lower-left corner */
- X else
- X y -= t->h_char/2;
- X (void) draw_text(x, y, s, i, 0, -1, j, d*Pi/2);
- X }
- X}
- X
- Xput_lab(x,y,s,d,size)
- Xint x, y, d, size;
- Xchar *s;
- X/* put label centered around (x,y), fitting it within given size, use vector font if only allowed */
- X{
- X int i, j, l;
- X
- X if (!s || !*s || size<=0)
- X return; /* nothing useful */
- X
- X j = size / t->h_char; /* number of standard chars that can fit */
- X i = (l=strlen(s)) < howmuch ? howmuch : l; /* how many chars should we fit ? */
- X
- X if (vect_font == F_NEVER || /* never use vector font */
- X !d && i <= j && vect_font != F_ALWYS) { /* horizontal, fits within req. size, no need for font */
- X if (tstate != d)
- X (*t->text_angle)(tstate = d);
- X make_just(&x, &y, CENTRE, strlen(s), d);
- X (*t->put_text)(x, y, s);
- X }
- X else { /* pain in the ass */
- X if (d)
- X x += t->h_char/2; /* draw_text takes lower-left corner */
- X else
- X y -= t->v_char/2;
- X i = t->v_char;
- X (void) draw_text(x, y, s, i, size, -1, CENTRE, d*Pi/2);
- X }
- X}
- X
- Xchar *make_labl(d)
- Xdouble d;
- X{
- X static char buf[200];
- X if (d == VERYLARGE || d== -VERYLARGE)
- X return(NULL); /* will be rejected later */
- X sprintf(buf, tic_form, (float) d); /* it's float from user point of view, and compatibility with Gnuplot */
- X return(buf);
- X}
- X
- Xset_hm(min, max)
- Xdouble min, max;
- X/* find space needed for ticks */
- X{
- X char buf[200];
- X int i;
- X sprintf(buf, tic_form, (float) min);
- X howmuch = strlen(buf);
- X sprintf(buf, tic_form, (float) max);
- X if (howmuch < (i=strlen(buf)))
- X howmuch = i;
- X}
- X
- Xinit_acrs()
- X/* init across pointer structure */
- X{
- X struct dfile *f = &data_head;
- X int i = 0;
- X
- X while (f = f->dnxt) {
- X across[i].chnp = f->data;
- X across[i++].vindex = 0;
- X }
- X}
- X
- X/* test terminal by drawing border and text */
- X/* called from command test */
- Xterm_test()
- X/* don't use original test_term() from term.c */
- X{
- X char *str;
- X int x,y, xl,yl, i;
- X char label[MAX_LINE_LEN];
- X
- X t = &term_tbl[term];
- X if (!term_init) {
- X (*t->init)();
- X term_init = TRUE;
- X }
- X screen_ok = FALSE;
- X (*t->graphics)();
- X /* border linetype */
- X (*t->linetype)(-2);
- X (*t->move)(0,0);
- X (*t->vector)(t->xmax-1,0);
- X (*t->vector)(t->xmax-1,t->ymax-1);
- X (*t->vector)(0,t->ymax-1);
- X (*t->vector)(0,0);
- X (void) (*t->justify_text)(LEFT);
- X (*t->put_text)(t->h_char*5,t->ymax-t->v_char*3,"Terminal Test");
- X (*t->linetype)(0);
- X (*t->arrow)(t->h_char*5, t->ymax-t->v_char*5, t->h_char*5, t->ymax/2+t->v_char);
- X /* axis linetype */
- X (*t->linetype)(-1);
- X (*t->move)(t->xmax/2,0);
- X (*t->vector)(t->xmax/2,t->ymax-1);
- X (*t->move)(0,t->ymax/2);
- X (*t->vector)(t->xmax-1,t->ymax/2);
- X /* test width and height of characters */
- X (*t->linetype)(-2);
- X (*t->move)( t->xmax/2-t->h_char*10,t->ymax/2+t->v_char/2);
- X (*t->vector)(t->xmax/2+t->h_char*10,t->ymax/2+t->v_char/2);
- X (*t->vector)(t->xmax/2+t->h_char*10,t->ymax/2-t->v_char/2);
- X (*t->vector)(t->xmax/2-t->h_char*10,t->ymax/2-t->v_char/2);
- X (*t->vector)(t->xmax/2-t->h_char*10,t->ymax/2+t->v_char/2);
- X (*t->put_text)(t->xmax/2-t->h_char*10,t->ymax/2,
- X "12345678901234567890");
- X /* test justification */
- X (void) (*t->justify_text)(LEFT);
- X (*t->put_text)(t->xmax/2,t->ymax/2+t->v_char*5,"left justified");
- X str = "centre+d text";
- X if ((*t->justify_text)(CENTRE))
- X (*t->put_text)(t->xmax/2,
- X t->ymax/2+t->v_char*4,str);
- X else
- X (*t->put_text)(t->xmax/2-strlen(str)*t->h_char/2,
- X t->ymax/2+t->v_char*4,str);
- X str = "right justified";
- X if ((*t->justify_text)(RIGHT))
- X (*t->put_text)(t->xmax/2,
- X t->ymax/2+t->v_char*3,str);
- X else
- X (*t->put_text)(t->xmax/2-strlen(str)*t->h_char,
- X t->ymax/2+t->v_char*3,str);
- X /* test text angle */
- X str = "rotated ce+ntred text";
- X if ((*t->text_angle)(1)) {
- X if ((*t->justify_text)(CENTRE))
- X (*t->put_text)(t->v_char,
- X t->ymax/2,str);
- X else
- X (*t->put_text)(t->v_char,
- X t->ymax/2-strlen(str)*t->h_char/2,str);
- X }
- X else {
- X (void) (*t->justify_text)(LEFT);
- X (*t->put_text)(t->h_char*2,t->ymax/2-t->v_char*2,"Can't rotate text");
- X }
- X (void) (*t->justify_text)(LEFT);
- X (void) (*t->text_angle)(0);
- X /* test tic size */
- X (*t->move)(t->xmax/2+t->h_tic*2,0);
- X (*t->vector)(t->xmax/2+t->h_tic*2,t->v_tic);
- X (*t->move)(t->xmax/2,t->v_tic*2);
- X (*t->vector)(t->xmax/2+t->h_tic,t->v_tic*2);
- X (*t->put_text)(t->xmax/2+t->h_tic*2,t->v_tic*2+t->v_char/2,"test tics");
- X /* test line and point types */
- X x = t->xmax - t->h_char*4 - t->h_tic*4;
- X y = t->ymax - t->v_char;
- X for ( i = -2; y > t->v_char; i++ ) {
- X (*t->linetype)(i);
- X (void) sprintf(label,"%d",i);
- X if ((*t->justify_text)(RIGHT))
- X (*t->put_text)(x,y,label);
- X else
- X (*t->put_text)(x-strlen(label)*t->h_char,y,label);
- X (*t->move)(x+t->h_char,y);
- X (*t->vector)(x+t->h_char*4,y);
- X y -= t->v_char;
- X }
- X /* test bars */
- X (*t->linetype)(-1);
- X x = t->xmax/2 + t->xmax/12;
- X y = t->ymax/6;
- X xl = t->xmax/32;
- X yl = t->ymax/32;
- X (*t->move)(x,y);
- X (*t->vector)(x+xl*6,y);
- X x += xl/4;
- X for (i=1; i<=4; i++, x+=xl*3/2) {
- X (*t->linetype)(i-1);
- X put_bar(x,y,xl,i*yl,FALSE);
- X }
- X /* test pies */
- X (*t->linetype)(0);
- X x = t->xmax/4;
- X y = t->ymax/4;
- X i = 3*(t->xmax < t->ymax ? t->xmax : t->ymax)/32;
- X xl = MCx(0,i,Pi/4);
- X yl = MCy(0,i,Pi/4);
- X (*t->move)(x+xl,y+yl);
- X (*t->vector)(x-xl,y-yl);
- X (*t->move)(x-xl,y+yl);
- X (*t->vector)(x+xl,y-yl);
- X put_arc(x,y,i,Pi/4,3*Pi/2);
- X sprintf(label,"(pie sampling is %d)",samples);
- X put_txt(x,y-yl-2*(int)(t->v_char),label,CENTRE,0);
- X x += t->xmax/32;
- X (*t->move)(x+xl,y-yl);
- X (*t->vector)(x,y);
- X (*t->vector)(x+xl,y+yl);
- X put_arc(x,y,i,Pi/4,-Pi/2);
- X
- X /* experimental code */
- X (*t->linetype)(0);
- X x = t->xmax/2 + t->xmax/32;
- X y = t->ymax*9/10;
- X i = t->v_char;
- X x += draw_text(x, y, "experimental", i, 0, -1, LEFT, 0.0);
- X i = draw_text(x, y, "scalable", i*2, 0, -1, LEFT, -Pi/4);
- X x += i*cos(-Pi/4); y += i*sin(-Pi/4);
- X (void) draw_text(x, y, "vector font", 0, (int)(t->xmax/16), -1, LEFT, -Pi/2);
- X y -= (int)(t->xmax/16);
- X (void) draw_text(x, y, "0123456789", 0, (int)(t->xmax/8), -1, LEFT, -Pi);
- X
- X /* and back into text mode */
- X (*t->text)();
- X (void) fflush(outfile);
- X}
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X/* included file contains an old version of graphics routines */
- X
- X#include "fstyles.i"
- X
- X
- X
- X
- X
- SHAR_EOF
- $TOUCH -am 0604152590 fgraf.c &&
- chmod 0666 fgraf.c ||
- echo "restore of fgraf.c failed"
- set `wc -c fgraf.c`;Wc_c=$1
- if test "$Wc_c" != "22428"; then
- echo original size 22428, current size $Wc_c
- fi
- echo "End of part 2, continue with part 3"
- exit 0
-