[BACK]Return to misc.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gnuplot

Annotation of OpenXM_contrib/gnuplot/misc.c, Revision 1.1

1.1     ! maekawa     1: #ifndef lint
        !             2: static char *RCSid = "$Id: misc.c,v 1.79 1998/04/14 00:16:02 drd Exp $";
        !             3: #endif
        !             4:
        !             5: /* GNUPLOT - misc.c */
        !             6:
        !             7: /*[
        !             8:  * Copyright 1986 - 1993, 1998   Thomas Williams, Colin Kelley
        !             9:  *
        !            10:  * Permission to use, copy, and distribute this software and its
        !            11:  * documentation for any purpose with or without fee is hereby granted,
        !            12:  * provided that the above copyright notice appear in all copies and
        !            13:  * that both that copyright notice and this permission notice appear
        !            14:  * in supporting documentation.
        !            15:  *
        !            16:  * Permission to modify the software is granted, but not the right to
        !            17:  * distribute the complete modified source code.  Modifications are to
        !            18:  * be distributed as patches to the released version.  Permission to
        !            19:  * distribute binaries produced by compiling modified sources is granted,
        !            20:  * provided you
        !            21:  *   1. distribute the corresponding source modifications from the
        !            22:  *    released version in the form of a patch file along with the binaries,
        !            23:  *   2. add special version identification to distinguish your version
        !            24:  *    in addition to the base release version number,
        !            25:  *   3. provide your name and address as the primary contact for the
        !            26:  *    support of your modified version, and
        !            27:  *   4. retain our contact information in regard to use of the base
        !            28:  *    software.
        !            29:  * Permission to distribute the released version of the source code along
        !            30:  * with corresponding source modifications in the form of a patch file is
        !            31:  * granted with same provisions 2 through 4 for binary distributions.
        !            32:  *
        !            33:  * This software is provided "as is" without express or implied warranty
        !            34:  * to the extent permitted by applicable law.
        !            35: ]*/
        !            36:
        !            37: #ifdef AMIGA_AC_5
        !            38: # include <exec/types.h>
        !            39: #endif /* AMIGA_AC_5 */
        !            40:
        !            41: #include "plot.h"
        !            42: #include "setshow.h"
        !            43:
        !            44: extern int key_vpos, key_hpos, key_just;
        !            45: extern int datatype[];
        !            46: extern char timefmt[];
        !            47:
        !            48: static void save_range __PROTO((FILE * fp, int axis, double min, double max, int autosc, char *text));
        !            49: static void save_tics __PROTO((FILE * fp, int where, int axis, struct ticdef * tdef, TBOOLEAN rotate, char *text));
        !            50: static void save_position __PROTO((FILE * fp, struct position * pos));
        !            51: static void save_functions__sub __PROTO((FILE * fp));
        !            52: static void save_variables__sub __PROTO((FILE * fp));
        !            53: static int lf_pop __PROTO((void));
        !            54: static void lf_push __PROTO((FILE * fp));
        !            55: static int find_maxl_cntr __PROTO((struct gnuplot_contours * contours, int *count));
        !            56:
        !            57:
        !            58: #define SAVE_NUM_OR_TIME(fp, x, axis) \
        !            59: do{if (datatype[axis]==TIME) { \
        !            60:   char s[80]; char *p; \
        !            61:   putc('"', fp);   \
        !            62:   gstrftime(s,80,timefmt,(double)(x)); \
        !            63:   for(p=s; *p; ++p) {\
        !            64:    if ( *p == '\t' ) fputs("\\t",fp);\
        !            65:    else if (*p == '\n') fputs("\\n",fp); \
        !            66:    else if ( *p > 126 || *p < 32 ) fprintf(fp,"\\%03o",*p);\
        !            67:    else putc(*p, fp);\
        !            68:   }\
        !            69:   putc('"', fp);\
        !            70:  } else {\
        !            71:   fprintf(fp,"%g",x);\
        !            72: }} while(0)
        !            73:
        !            74:
        !            75: /* State information for load_file(), to recover from errors
        !            76:  * and properly handle recursive load_file calls
        !            77:  */
        !            78: typedef struct lf_state_struct LFS;
        !            79: struct lf_state_struct {
        !            80:     FILE *fp;                  /* file pointer for load file */
        !            81:     char *name;                        /* name of file */
        !            82:     TBOOLEAN interactive;      /* value of interactive flag on entry */
        !            83:     TBOOLEAN do_load_arg_substitution; /* likewise ... */
        !            84:     int inline_num;            /* inline_num on entry */
        !            85:     LFS *prev;                 /* defines a stack */
        !            86:     char *call_args[10];       /* args when file is 'call'ed instead of 'load'ed */
        !            87: } *lf_head = NULL;             /* NULL if not in load_file */
        !            88:
        !            89: /* these two could be in load_file, except for error recovery */
        !            90: extern TBOOLEAN do_load_arg_substitution;
        !            91: extern char *call_args[10];
        !            92:
        !            93: /*
        !            94:  * cp_alloc() allocates a curve_points structure that can hold 'num'
        !            95:  * points.
        !            96:  */
        !            97: struct curve_points *
        !            98:  cp_alloc(num)
        !            99: int num;
        !           100: {
        !           101:     struct curve_points *cp;
        !           102:
        !           103:     cp = (struct curve_points *) gp_alloc((unsigned long) sizeof(struct curve_points), "curve");
        !           104:     cp->p_max = (num >= 0 ? num : 0);
        !           105:
        !           106:     if (num > 0) {
        !           107:        cp->points = (struct coordinate GPHUGE *)
        !           108:            gp_alloc((unsigned long) num * sizeof(struct coordinate), "curve points");
        !           109:     } else
        !           110:        cp->points = (struct coordinate GPHUGE *) NULL;
        !           111:     cp->next_cp = NULL;
        !           112:     cp->title = NULL;
        !           113:     return (cp);
        !           114: }
        !           115:
        !           116:
        !           117: /*
        !           118:  * cp_extend() reallocates a curve_points structure to hold "num"
        !           119:  * points. This will either expand or shrink the storage.
        !           120:  */
        !           121: void cp_extend(cp, num)
        !           122: struct curve_points *cp;
        !           123: int num;
        !           124: {
        !           125:
        !           126: #if defined(DOS16) || defined(WIN16)
        !           127:     /* Make sure we do not allocate more than 64k points in msdos since
        !           128:        * indexing is done with 16-bit int
        !           129:        * Leave some bytes for malloc maintainance.
        !           130:      */
        !           131:     if (num > 32700)
        !           132:        int_error("Array index must be less than 32k in msdos", NO_CARET);
        !           133: #endif /* MSDOS */
        !           134:
        !           135:     if (num == cp->p_max)
        !           136:        return;
        !           137:
        !           138:     if (num > 0) {
        !           139:        if (cp->points == NULL) {
        !           140:            cp->points = (struct coordinate GPHUGE *)
        !           141:                gp_alloc((unsigned long) num * sizeof(struct coordinate), "curve points");
        !           142:        } else {
        !           143:            cp->points = (struct coordinate GPHUGE *)
        !           144:                gp_realloc(cp->points, (unsigned long) num * sizeof(struct coordinate), "expanding curve points");
        !           145:        }
        !           146:        cp->p_max = num;
        !           147:     } else {
        !           148:        if (cp->points != (struct coordinate GPHUGE *) NULL)
        !           149:            free(cp->points);
        !           150:        cp->points = (struct coordinate GPHUGE *) NULL;
        !           151:        cp->p_max = 0;
        !           152:     }
        !           153: }
        !           154:
        !           155: /*
        !           156:  * cp_free() releases any memory which was previously malloc()'d to hold
        !           157:  *   curve points (and recursively down the linked list).
        !           158:  */
        !           159: void cp_free(cp)
        !           160: struct curve_points *cp;
        !           161: {
        !           162:     if (cp) {
        !           163:        cp_free(cp->next_cp);
        !           164:        if (cp->title)
        !           165:            free((char *) cp->title);
        !           166:        if (cp->points)
        !           167:            free((char *) cp->points);
        !           168:        free((char *) cp);
        !           169:     }
        !           170: }
        !           171:
        !           172: /*
        !           173:  * iso_alloc() allocates a iso_curve structure that can hold 'num'
        !           174:  * points.
        !           175:  */
        !           176: struct iso_curve *
        !           177:  iso_alloc(num)
        !           178: int num;
        !           179: {
        !           180:     struct iso_curve *ip;
        !           181:     ip = (struct iso_curve *) gp_alloc((unsigned long) sizeof(struct iso_curve), "iso curve");
        !           182:     ip->p_max = (num >= 0 ? num : 0);
        !           183:     if (num > 0) {
        !           184:        ip->points = (struct coordinate GPHUGE *)
        !           185:            gp_alloc((unsigned long) num * sizeof(struct coordinate), "iso curve points");
        !           186:     } else
        !           187:        ip->points = (struct coordinate GPHUGE *) NULL;
        !           188:     ip->next = NULL;
        !           189:     return (ip);
        !           190: }
        !           191:
        !           192: /*
        !           193:  * iso_extend() reallocates a iso_curve structure to hold "num"
        !           194:  * points. This will either expand or shrink the storage.
        !           195:  */
        !           196: void iso_extend(ip, num)
        !           197: struct iso_curve *ip;
        !           198: int num;
        !           199: {
        !           200:     if (num == ip->p_max)
        !           201:        return;
        !           202:
        !           203: #if defined(DOS16) || defined(WIN16)
        !           204:     /* Make sure we do not allocate more than 64k points in msdos since
        !           205:        * indexing is done with 16-bit int
        !           206:        * Leave some bytes for malloc maintainance.
        !           207:      */
        !           208:     if (num > 32700)
        !           209:        int_error("Array index must be less than 32k in msdos", NO_CARET);
        !           210: #endif /* 16bit (Win)Doze */
        !           211:
        !           212:     if (num > 0) {
        !           213:        if (ip->points == NULL) {
        !           214:            ip->points = (struct coordinate GPHUGE *)
        !           215:                gp_alloc((unsigned long) num * sizeof(struct coordinate), "iso curve points");
        !           216:        } else {
        !           217:            ip->points = (struct coordinate GPHUGE *)
        !           218:                gp_realloc(ip->points, (unsigned long) num * sizeof(struct coordinate), "expanding curve points");
        !           219:        }
        !           220:        ip->p_max = num;
        !           221:     } else {
        !           222:        if (ip->points != (struct coordinate GPHUGE *) NULL)
        !           223:            free(ip->points);
        !           224:        ip->points = (struct coordinate GPHUGE *) NULL;
        !           225:        ip->p_max = 0;
        !           226:     }
        !           227: }
        !           228:
        !           229: /*
        !           230:  * iso_free() releases any memory which was previously malloc()'d to hold
        !           231:  *   iso curve points.
        !           232:  */
        !           233: void iso_free(ip)
        !           234: struct iso_curve *ip;
        !           235: {
        !           236:     if (ip) {
        !           237:        if (ip->points)
        !           238:            free((char *) ip->points);
        !           239:        free((char *) ip);
        !           240:     }
        !           241: }
        !           242:
        !           243: /*
        !           244:  * sp_alloc() allocates a surface_points structure that can hold 'num_iso_1'
        !           245:  * iso-curves with 'num_samp_2' samples and 'num_iso_2' iso-curves with
        !           246:  * 'num_samp_1' samples.
        !           247:  * If, however num_iso_2 or num_samp_1 is zero no iso curves are allocated.
        !           248:  */
        !           249: struct surface_points *
        !           250:  sp_alloc(num_samp_1, num_iso_1, num_samp_2, num_iso_2)
        !           251: int num_samp_1, num_iso_1, num_samp_2, num_iso_2;
        !           252: {
        !           253:     struct surface_points *sp;
        !           254:
        !           255:     sp = (struct surface_points *) gp_alloc((unsigned long) sizeof(struct surface_points), "surface");
        !           256:     sp->next_sp = NULL;
        !           257:     sp->title = NULL;
        !           258:     sp->contours = NULL;
        !           259:     sp->iso_crvs = NULL;
        !           260:     sp->num_iso_read = 0;
        !           261:
        !           262:     if (num_iso_2 > 0 && num_samp_1 > 0) {
        !           263:        int i;
        !           264:        struct iso_curve *icrv;
        !           265:
        !           266:        for (i = 0; i < num_iso_1; i++) {
        !           267:            icrv = iso_alloc(num_samp_2);
        !           268:            icrv->next = sp->iso_crvs;
        !           269:            sp->iso_crvs = icrv;
        !           270:        }
        !           271:        for (i = 0; i < num_iso_2; i++) {
        !           272:            icrv = iso_alloc(num_samp_1);
        !           273:            icrv->next = sp->iso_crvs;
        !           274:            sp->iso_crvs = icrv;
        !           275:        }
        !           276:     } else
        !           277:        sp->iso_crvs = (struct iso_curve *) NULL;
        !           278:
        !           279:     return (sp);
        !           280: }
        !           281:
        !           282: /*
        !           283:  * sp_replace() updates a surface_points structure so it can hold 'num_iso_1'
        !           284:  * iso-curves with 'num_samp_2' samples and 'num_iso_2' iso-curves with
        !           285:  * 'num_samp_1' samples.
        !           286:  * If, however num_iso_2 or num_samp_1 is zero no iso curves are allocated.
        !           287:  */
        !           288: void sp_replace(sp, num_samp_1, num_iso_1, num_samp_2, num_iso_2)
        !           289: struct surface_points *sp;
        !           290: int num_samp_1, num_iso_1, num_samp_2, num_iso_2;
        !           291: {
        !           292:     int i;
        !           293:     struct iso_curve *icrv, *icrvs = sp->iso_crvs;
        !           294:
        !           295:     while (icrvs) {
        !           296:        icrv = icrvs;
        !           297:        icrvs = icrvs->next;
        !           298:        iso_free(icrv);
        !           299:     }
        !           300:     sp->iso_crvs = NULL;
        !           301:
        !           302:     if (num_iso_2 > 0 && num_samp_1 > 0) {
        !           303:        for (i = 0; i < num_iso_1; i++) {
        !           304:            icrv = iso_alloc(num_samp_2);
        !           305:            icrv->next = sp->iso_crvs;
        !           306:            sp->iso_crvs = icrv;
        !           307:        }
        !           308:        for (i = 0; i < num_iso_2; i++) {
        !           309:            icrv = iso_alloc(num_samp_1);
        !           310:            icrv->next = sp->iso_crvs;
        !           311:            sp->iso_crvs = icrv;
        !           312:        }
        !           313:     } else
        !           314:        sp->iso_crvs = (struct iso_curve *) NULL;
        !           315: }
        !           316:
        !           317: /*
        !           318:  * sp_free() releases any memory which was previously malloc()'d to hold
        !           319:  *   surface points.
        !           320:  */
        !           321: void sp_free(sp)
        !           322: struct surface_points *sp;
        !           323: {
        !           324:     if (sp) {
        !           325:        sp_free(sp->next_sp);
        !           326:        if (sp->title)
        !           327:            free((char *) sp->title);
        !           328:        if (sp->contours) {
        !           329:            struct gnuplot_contours *cntr, *cntrs = sp->contours;
        !           330:
        !           331:            while (cntrs) {
        !           332:                cntr = cntrs;
        !           333:                cntrs = cntrs->next;
        !           334:                free(cntr->coords);
        !           335:                free(cntr);
        !           336:            }
        !           337:        }
        !           338:        if (sp->iso_crvs) {
        !           339:            struct iso_curve *icrv, *icrvs = sp->iso_crvs;
        !           340:
        !           341:            while (icrvs) {
        !           342:                icrv = icrvs;
        !           343:                icrvs = icrvs->next;
        !           344:                iso_free(icrv);
        !           345:            }
        !           346:        }
        !           347:        free((char *) sp);
        !           348:     }
        !           349: }
        !           350:
        !           351:
        !           352: /*
        !           353:  *  functions corresponding to the arguments of the GNUPLOT `save` command
        !           354:  */
        !           355: void save_functions(fp)
        !           356: FILE *fp;
        !           357: {
        !           358:     if (fp) {
        !           359:        show_version(fp);               /* I _love_ information written */
        !           360:        save_functions__sub(fp);        /* at the top and the end of an */
        !           361:        fputs("#    EOF\n", fp);        /* human readable ASCII file.   */
        !           362:        (void) fclose(fp);      /*                        (JFi) */
        !           363:     } else
        !           364:        os_error("Cannot open save file", c_token);
        !           365: }
        !           366:
        !           367:
        !           368: void save_variables(fp)
        !           369: FILE *fp;
        !           370: {
        !           371:     if (fp) {
        !           372:        show_version(fp);
        !           373:        save_variables__sub(fp);
        !           374:        fputs("#    EOF\n", fp);
        !           375:        (void) fclose(fp);
        !           376:     } else
        !           377:        os_error("Cannot open save file", c_token);
        !           378: }
        !           379:
        !           380:
        !           381: void save_set(fp)
        !           382: FILE *fp;
        !           383: {
        !           384:     if (fp) {
        !           385:        show_version(fp);
        !           386:        save_set_all(fp);
        !           387:        fputs("#    EOF\n", fp);
        !           388:        (void) fclose(fp);
        !           389:     } else
        !           390:        os_error("Cannot open save file", c_token);
        !           391: }
        !           392:
        !           393:
        !           394: void save_all(fp)
        !           395: FILE *fp;
        !           396: {
        !           397:     if (fp) {
        !           398:        show_version(fp);
        !           399:        save_set_all(fp);
        !           400:        save_functions__sub(fp);
        !           401:        save_variables__sub(fp);
        !           402:        fprintf(fp, "%s\n", replot_line);
        !           403:         if (wri_to_fil_last_fit_cmd(NULL)) {
        !           404:            fputs("## ", fp);
        !           405:            wri_to_fil_last_fit_cmd(fp);
        !           406:            putc('\n', fp);
        !           407:         }
        !           408:        fputs("#    EOF\n", fp);
        !           409:        (void) fclose(fp);
        !           410:     } else
        !           411:        os_error("Cannot open save file", c_token);
        !           412: }
        !           413:
        !           414: /*
        !           415:  *  auxiliary functions
        !           416:  */
        !           417:
        !           418: static void save_functions__sub(fp)
        !           419: FILE *fp;
        !           420: {
        !           421:     register struct udft_entry *udf = first_udf;
        !           422:
        !           423:     while (udf) {
        !           424:        if (udf->definition) {
        !           425:            fprintf(fp, "%s\n", udf->definition);
        !           426:        }
        !           427:        udf = udf->next_udf;
        !           428:     }
        !           429: }
        !           430:
        !           431: static void save_variables__sub(fp)
        !           432: FILE *fp;
        !           433: {
        !           434:     register struct udvt_entry *udv = first_udv->next_udv;     /* always skip pi */
        !           435:
        !           436:     while (udv) {
        !           437:        if (!udv->udv_undef) {
        !           438:            fprintf(fp, "%s = ", udv->udv_name);
        !           439:            disp_value(fp, &(udv->udv_value));
        !           440:            (void) putc('\n', fp);
        !           441:        }
        !           442:        udv = udv->next_udv;
        !           443:     }
        !           444: }
        !           445:
        !           446: void save_set_all(fp)
        !           447: FILE *fp;
        !           448: {
        !           449:     struct text_label *this_label;
        !           450:     struct arrow_def *this_arrow;
        !           451:     struct linestyle_def *this_linestyle;
        !           452:     char str[MAX_LINE_LEN + 1];
        !           453:
        !           454:     /* opinions are split as to whether we save term and outfile
        !           455:      * as a compromise, we output them as comments !
        !           456:      */
        !           457:     if (term)
        !           458:        fprintf(fp, "# set terminal %s %s\n", term->name, term_options);
        !           459:     else
        !           460:        fputs("# set terminal unknown\n", fp);
        !           461:
        !           462:     if (outstr)
        !           463:        fprintf(fp, "# set output '%s'\n", outstr);
        !           464:     else
        !           465:        fputs("# set output\n", fp);
        !           466:
        !           467:     fprintf(fp, "\
        !           468: set %sclip points\n\
        !           469: set %sclip one\n\
        !           470: set %sclip two\n\
        !           471: set bar %f\n",
        !           472:            (clip_points) ? "" : "no",
        !           473:            (clip_lines1) ? "" : "no",
        !           474:            (clip_lines2) ? "" : "no",
        !           475:            bar_size);
        !           476:
        !           477:     if (draw_border)
        !           478:        /* HBB 980609: handle border linestyle, too */
        !           479:        fprintf(fp, "set border %d lt %d lw %.3f\n", draw_border, border_lp.l_type + 1, border_lp.l_width);
        !           480:     else
        !           481:        fprintf(fp, "set noborder\n");
        !           482:
        !           483:     fprintf(fp, "\
        !           484: set xdata%s\n\
        !           485: set ydata%s\n\
        !           486: set zdata%s\n\
        !           487: set x2data%s\n\
        !           488: set y2data%s\n",
        !           489:            datatype[FIRST_X_AXIS] == TIME ? " time" : "",
        !           490:            datatype[FIRST_Y_AXIS] == TIME ? " time" : "",
        !           491:            datatype[FIRST_Z_AXIS] == TIME ? " time" : "",
        !           492:            datatype[SECOND_X_AXIS] == TIME ? " time" : "",
        !           493:            datatype[SECOND_Y_AXIS] == TIME ? " time" : "");
        !           494:
        !           495:     if (boxwidth < 0.0)
        !           496:        fputs("set boxwidth\n", fp);
        !           497:     else
        !           498:        fprintf(fp, "set boxwidth %g\n", boxwidth);
        !           499:     if (dgrid3d)
        !           500:        fprintf(fp, "set dgrid3d %d,%d, %d\n",
        !           501:                dgrid3d_row_fineness,
        !           502:                dgrid3d_col_fineness,
        !           503:                dgrid3d_norm_value);
        !           504:
        !           505:     fprintf(fp, "\
        !           506: set dummy %s,%s\n\
        !           507: set format x \"%s\"\n\
        !           508: set format y \"%s\"\n\
        !           509: set format x2 \"%s\"\n\
        !           510: set format y2 \"%s\"\n\
        !           511: set format z \"%s\"\n\
        !           512: set angles %s\n",
        !           513:            dummy_var[0], dummy_var[1],
        !           514:            conv_text(str, xformat),
        !           515:            conv_text(str, yformat),
        !           516:            conv_text(str, x2format),
        !           517:            conv_text(str, y2format),
        !           518:            conv_text(str, zformat),
        !           519:            (angles_format == ANGLES_RADIANS) ? "radians" : "degrees");
        !           520:
        !           521:     if (work_grid.l_type == 0)
        !           522:        fputs("set nogrid\n", fp);
        !           523:     else {
        !           524:        if (polar_grid_angle)   /* set angle already output */
        !           525:            fprintf(fp, "set grid polar %f\n", polar_grid_angle / ang2rad);
        !           526:        else
        !           527:            fputs("set grid nopolar\n", fp);
        !           528:        fprintf(fp, "set grid %sxtics %sytics %sztics %sx2tics %sy2tics %smxtics %smytics %smztics %smx2tics %smy2tics lt %d lw %.3f, lt %d lw %.3f\n",
        !           529:                work_grid.l_type & GRID_X ? "" : "no",
        !           530:                work_grid.l_type & GRID_Y ? "" : "no",
        !           531:                work_grid.l_type & GRID_Z ? "" : "no",
        !           532:                work_grid.l_type & GRID_X2 ? "" : "no",
        !           533:                work_grid.l_type & GRID_Y2 ? "" : "no",
        !           534:                work_grid.l_type & GRID_MX ? "" : "no",
        !           535:                work_grid.l_type & GRID_MY ? "" : "no",
        !           536:                work_grid.l_type & GRID_MZ ? "" : "no",
        !           537:                work_grid.l_type & GRID_MX2 ? "" : "no",
        !           538:                work_grid.l_type & GRID_MY2 ? "" : "no",
        !           539:                grid_lp.l_type + 1, grid_lp.l_width,
        !           540:                mgrid_lp.l_type + 1, mgrid_lp.l_width);
        !           541:     }
        !           542:     fprintf(fp, "set key title \"%s\"\n", conv_text(str, key_title));
        !           543:     switch (key) {
        !           544:     case -1:{
        !           545:            fputs("set key", fp);
        !           546:            switch (key_hpos) {
        !           547:            case TRIGHT:
        !           548:                fputs(" right", fp);
        !           549:                break;
        !           550:            case TLEFT:
        !           551:                fputs(" left", fp);
        !           552:                break;
        !           553:            case TOUT:
        !           554:                fputs(" out", fp);
        !           555:                break;
        !           556:            }
        !           557:            switch (key_vpos) {
        !           558:            case TTOP:
        !           559:                fputs(" top", fp);
        !           560:                break;
        !           561:            case TBOTTOM:
        !           562:                fputs(" bottom", fp);
        !           563:                break;
        !           564:            case TUNDER:
        !           565:                fputs(" below", fp);
        !           566:                break;
        !           567:            }
        !           568:            break;
        !           569:        }
        !           570:     case 0:
        !           571:        fputs("set nokey\n", fp);
        !           572:        break;
        !           573:     case 1:
        !           574:        fputs("set key ", fp);
        !           575:        save_position(fp, &key_user_pos);
        !           576:        break;
        !           577:     }
        !           578:     if (key) {
        !           579:        fprintf(fp, " %s %sreverse box linetype %d linewidth %.3f samplen %g spacing %g width %g\n",
        !           580:                key_just == JLEFT ? "Left" : "Right",
        !           581:                key_reverse ? "" : "no",
        !           582:                key_box.l_type + 1, key_box.l_width, key_swidth, key_vert_factor, key_width_fix);
        !           583:     }
        !           584:     fputs("set nolabel\n", fp);
        !           585:     for (this_label = first_label; this_label != NULL;
        !           586:         this_label = this_label->next) {
        !           587:        fprintf(fp, "set label %d \"%s\" at ",
        !           588:                this_label->tag,
        !           589:                conv_text(str, this_label->text));
        !           590:        save_position(fp, &this_label->place);
        !           591:
        !           592:        switch (this_label->pos) {
        !           593:        case LEFT:
        !           594:            fputs(" left", fp);
        !           595:            break;
        !           596:        case CENTRE:
        !           597:            fputs(" centre", fp);
        !           598:            break;
        !           599:        case RIGHT:
        !           600:            fputs(" right", fp);
        !           601:            break;
        !           602:        }
        !           603:        fprintf(fp, " %srotate", this_label->rotate ? "" : "no");
        !           604:        if ((this_label->font)[0] != NUL)
        !           605:            fprintf(fp, " font \"%s\"", this_label->font);
        !           606:        /* Entry font added by DJL */
        !           607:        fputc('\n', fp);
        !           608:     }
        !           609:     fputs("set noarrow\n", fp);
        !           610:     for (this_arrow = first_arrow; this_arrow != NULL;
        !           611:         this_arrow = this_arrow->next) {
        !           612:        fprintf(fp, "set arrow %d from ", this_arrow->tag);
        !           613:        save_position(fp, &this_arrow->start);
        !           614:        fputs(" to ", fp);
        !           615:        save_position(fp, &this_arrow->end);
        !           616:        fprintf(fp, " %s linetype %d linewidth %.3f\n",
        !           617:                this_arrow->head ? "" : " nohead",
        !           618:                this_arrow->lp_properties.l_type + 1,
        !           619:                this_arrow->lp_properties.l_width);
        !           620:     }
        !           621:     fputs("set nolinestyle\n", fp);
        !           622:     for (this_linestyle = first_linestyle; this_linestyle != NULL;
        !           623:         this_linestyle = this_linestyle->next) {
        !           624:        fprintf(fp, "set linestyle %d ", this_linestyle->tag);
        !           625:        fprintf(fp, "linetype %d linewidth %.3f pointtype %d pointsize %.3f\n",
        !           626:                this_linestyle->lp_properties.l_type + 1,
        !           627:                this_linestyle->lp_properties.l_width,
        !           628:                this_linestyle->lp_properties.p_type + 1,
        !           629:                this_linestyle->lp_properties.p_size);
        !           630:     }
        !           631:     fputs("set nologscale\n", fp);
        !           632:     if (is_log_x)
        !           633:        fprintf(fp, "set logscale x %g\n", base_log_x);
        !           634:     if (is_log_y)
        !           635:        fprintf(fp, "set logscale y %g\n", base_log_y);
        !           636:     if (is_log_z)
        !           637:        fprintf(fp, "set logscale z %g\n", base_log_z);
        !           638:     if (is_log_x2)
        !           639:        fprintf(fp, "set logscale x2 %g\n", base_log_x2);
        !           640:     if (is_log_y2)
        !           641:        fprintf(fp, "set logscale y2 %g\n", base_log_y2);
        !           642:
        !           643:     fprintf(fp, "\
        !           644: set offsets %g, %g, %g, %g\n\
        !           645: set pointsize %g\n\
        !           646: set encoding %s\n\
        !           647: set %spolar\n\
        !           648: set %sparametric\n\
        !           649: set view %g, %g, %g, %g\n\
        !           650: set samples %d, %d\n\
        !           651: set isosamples %d, %d\n\
        !           652: set %ssurface\n\
        !           653: set %scontour",
        !           654:            loff, roff, toff, boff,
        !           655:            pointsize,
        !           656:            encoding_names[encoding],
        !           657:            (polar) ? "" : "no",
        !           658:            (parametric) ? "" : "no",
        !           659:            surface_rot_x, surface_rot_z, surface_scale, surface_zscale,
        !           660:            samples_1, samples_2,
        !           661:            iso_samples_1, iso_samples_2,
        !           662:            (draw_surface) ? "" : "no",
        !           663:            (draw_contour) ? "" : "no");
        !           664:
        !           665:     switch (draw_contour) {
        !           666:     case CONTOUR_NONE:
        !           667:        fputc('\n', fp);
        !           668:        break;
        !           669:     case CONTOUR_BASE:
        !           670:        fputs(" base\n", fp);
        !           671:        break;
        !           672:     case CONTOUR_SRF:
        !           673:        fputs(" surface\n", fp);
        !           674:        break;
        !           675:     case CONTOUR_BOTH:
        !           676:        fputs(" both\n", fp);
        !           677:        break;
        !           678:     }
        !           679:     if (label_contours)
        !           680:        fprintf(fp, "set clabel '%s'\n", contour_format);
        !           681:     else
        !           682:        fputs("set noclabel\n", fp);
        !           683:
        !           684:     fputs("set mapping ", fp);
        !           685:     switch(mapping3d) {
        !           686:     case MAP3D_SPHERICAL:
        !           687:        fputs("spherical\n", fp);
        !           688:        break;
        !           689:     case MAP3D_CYLINDRICAL:
        !           690:        fputs("cylindrical\n", fp);
        !           691:        break;
        !           692:     case MAP3D_CARTESIAN:
        !           693:     default:
        !           694:        fputs("cartesian\n", fp);
        !           695:        break;
        !           696:     }
        !           697:
        !           698:     if (missing_val != NULL)
        !           699:        fprintf(fp, "set missing %s\n", missing_val);
        !           700:
        !           701:     save_hidden3doptions(fp);
        !           702:     fprintf(fp, "set cntrparam order %d\n", contour_order);
        !           703:     fputs("set cntrparam ", fp);
        !           704:     switch (contour_kind) {
        !           705:     case CONTOUR_KIND_LINEAR:
        !           706:        fputs("linear\n", fp);
        !           707:        break;
        !           708:     case CONTOUR_KIND_CUBIC_SPL:
        !           709:        fputs("cubicspline\n", fp);
        !           710:        break;
        !           711:     case CONTOUR_KIND_BSPLINE:
        !           712:        fputs("bspline\n", fp);
        !           713:        break;
        !           714:     }
        !           715:     fputs("set cntrparam levels ", fp);
        !           716:     switch (levels_kind) {
        !           717:     case LEVELS_AUTO:
        !           718:        fprintf(fp, "auto %d\n", contour_levels);
        !           719:        break;
        !           720:     case LEVELS_INCREMENTAL:
        !           721:        fprintf(fp, "incremental %g,%g,%g\n",
        !           722:                levels_list[0], levels_list[1],
        !           723:                levels_list[0] + levels_list[1] * contour_levels);
        !           724:        break;
        !           725:     case LEVELS_DISCRETE:
        !           726:        {
        !           727:            int i;
        !           728:            fprintf(fp, "discrete %g", levels_list[0]);
        !           729:            for (i = 1; i < contour_levels; i++)
        !           730:                fprintf(fp, ",%g ", levels_list[i]);
        !           731:            fputc('\n', fp);
        !           732:        }
        !           733:     }
        !           734:     fprintf(fp, "\
        !           735: set cntrparam points %d\n\
        !           736: set size ratio %g %g,%g\n\
        !           737: set origin %g,%g\n\
        !           738: set data style ",
        !           739:            contour_pts,
        !           740:            aspect_ratio, xsize, ysize,
        !           741:            xoffset, yoffset);
        !           742:
        !           743:     switch (data_style) {
        !           744:     case LINES:
        !           745:        fputs("lines\n", fp);
        !           746:        break;
        !           747:     case POINTSTYLE:
        !           748:        fputs("points\n", fp);
        !           749:        break;
        !           750:     case IMPULSES:
        !           751:        fputs("impulses\n", fp);
        !           752:        break;
        !           753:     case LINESPOINTS:
        !           754:        fputs("linespoints\n", fp);
        !           755:        break;
        !           756:     case DOTS:
        !           757:        fputs("dots\n", fp);
        !           758:        break;
        !           759:     case YERRORBARS:
        !           760:        fputs("yerrorbars\n", fp);
        !           761:        break;
        !           762:     case XERRORBARS:
        !           763:        fputs("xerrorbars\n", fp);
        !           764:        break;
        !           765:     case XYERRORBARS:
        !           766:        fputs("xyerrorbars\n", fp);
        !           767:        break;
        !           768:     case BOXES:
        !           769:        fputs("boxes\n", fp);
        !           770:        break;
        !           771:     case BOXERROR:
        !           772:        fputs("boxerrorbars\n", fp);
        !           773:        break;
        !           774:     case BOXXYERROR:
        !           775:        fputs("boxxyerrorbars\n", fp);
        !           776:        break;
        !           777:     case STEPS:
        !           778:        fputs("steps\n", fp);
        !           779:        break;                  /* JG */
        !           780:     case FSTEPS:
        !           781:        fputs("fsteps\n", fp);
        !           782:        break;                  /* HOE */
        !           783:     case HISTEPS:
        !           784:        fputs("histeps\n", fp);
        !           785:        break;                  /* CAC */
        !           786:     case VECTOR:
        !           787:        fputs("vector\n", fp);
        !           788:        break;
        !           789:     case FINANCEBARS:
        !           790:        fputs("financebars\n", fp);
        !           791:        break;
        !           792:     case CANDLESTICKS:
        !           793:        fputs("candlesticks\n", fp);
        !           794:        break;
        !           795:     }
        !           796:     fputs("set function style ", fp);
        !           797:     switch (func_style) {
        !           798:     case LINES:
        !           799:        fputs("lines\n", fp);
        !           800:        break;
        !           801:     case POINTSTYLE:
        !           802:        fputs("points\n", fp);
        !           803:        break;
        !           804:     case IMPULSES:
        !           805:        fputs("impulses\n", fp);
        !           806:        break;
        !           807:     case LINESPOINTS:
        !           808:        fputs("linespoints\n", fp);
        !           809:        break;
        !           810:     case DOTS:
        !           811:        fputs("dots\n", fp);
        !           812:        break;
        !           813:     case YERRORBARS:
        !           814:        fputs("yerrorbars\n", fp);
        !           815:        break;
        !           816:     case XERRORBARS:
        !           817:        fputs("xerrorbars\n", fp);
        !           818:        break;
        !           819:     case XYERRORBARS:
        !           820:        fputs("xyerrorbars\n", fp);
        !           821:        break;
        !           822:     case BOXXYERROR:
        !           823:        fputs("boxxyerrorbars\n", fp);
        !           824:        break;
        !           825:     case BOXES:
        !           826:        fputs("boxes\n", fp);
        !           827:        break;
        !           828:     case BOXERROR:
        !           829:        fputs("boxerrorbars\n", fp);
        !           830:        break;
        !           831:     case STEPS:
        !           832:        fputs("steps\n", fp);
        !           833:        break;                  /* JG */
        !           834:     case FSTEPS:
        !           835:        fputs("fsteps\n", fp);
        !           836:        break;                  /* HOE */
        !           837:     case HISTEPS:
        !           838:        fputs("histeps\n", fp);
        !           839:        break;                  /* CAC */
        !           840:     case VECTOR:
        !           841:        fputs("vector\n", fp);
        !           842:        break;
        !           843:     case FINANCEBARS:
        !           844:        fputs("financebars\n", fp);
        !           845:        break;
        !           846:     case CANDLESTICKS:
        !           847:        fputs("candlesticks\n", fp);
        !           848:        break;
        !           849:     default:
        !           850:         /* HBB: default case demanded by gcc, still needed ?? */
        !           851:        fputs("---error!---\n", fp);
        !           852:     }
        !           853:
        !           854:     fprintf(fp, "\
        !           855: set xzeroaxis lt %d lw %.3f\n\
        !           856: set x2zeroaxis lt %d lw %.3f\n\
        !           857: set yzeroaxis lt %d lw %.3f\n\
        !           858: set y2zeroaxis lt %d lw %.3f\n\
        !           859: set tics %s\n\
        !           860: set ticslevel %g\n\
        !           861: set ticscale %g %g\n",
        !           862:            xzeroaxis.l_type + 1, xzeroaxis.l_width,
        !           863:            x2zeroaxis.l_type + 1, x2zeroaxis.l_width,
        !           864:            yzeroaxis.l_type + 1, yzeroaxis.l_width,
        !           865:            y2zeroaxis.l_type + 1, y2zeroaxis.l_width,
        !           866:            (tic_in) ? "in" : "out",
        !           867:            ticslevel,
        !           868:            ticscale, miniticscale);
        !           869:
        !           870: #define SAVE_XYZLABEL(name,lab) { \
        !           871:   fprintf(fp, "set %s \"%s\" %f,%f ", \
        !           872:     name, conv_text(str,lab.text),lab.xoffset,lab.yoffset); \
        !           873:   fprintf(fp, " \"%s\"\n", conv_text(str, lab.font)); \
        !           874: }
        !           875:
        !           876:
        !           877: #define SAVE_MINI(name,m,freq) switch(m&TICS_MASK) { \
        !           878:  case 0: fprintf(fp, "set no%s\n", name); break; \
        !           879:  case MINI_AUTO: fprintf(fp, "set %s\n",name); break; \
        !           880:  case MINI_DEFAULT: fprintf(fp, "set %s default\n",name); break; \
        !           881:  case MINI_USER: fprintf(fp, "set %s %f\n", name, freq); break; \
        !           882: }
        !           883:     SAVE_MINI("mxtics", mxtics, mxtfreq)
        !           884:        SAVE_MINI("mytics", mytics, mytfreq)
        !           885:        SAVE_MINI("mx2tics", mx2tics, mx2tfreq)
        !           886:        SAVE_MINI("my2tics", my2tics, my2tfreq)
        !           887:        save_tics(fp, xtics, FIRST_X_AXIS, &xticdef, rotate_xtics, "x");
        !           888:     save_tics(fp, ytics, FIRST_Y_AXIS, &yticdef, rotate_ytics, "y");
        !           889:     save_tics(fp, ztics, FIRST_Z_AXIS, &zticdef, rotate_ztics, "z");
        !           890:     save_tics(fp, x2tics, SECOND_X_AXIS, &x2ticdef, rotate_x2tics, "x2");
        !           891:     save_tics(fp, y2tics, SECOND_Y_AXIS, &y2ticdef, rotate_y2tics, "y2");
        !           892:     SAVE_XYZLABEL("title", title);
        !           893:
        !           894:     fprintf(fp, "set %s \"%s\" %s %srotate %f,%f ",
        !           895:            "timestamp", conv_text(str, timelabel.text),
        !           896:            (timelabel_bottom ? "bottom" : "top"),
        !           897:            (timelabel_rotate ? "" : "no"),
        !           898:            timelabel.xoffset, timelabel.yoffset);
        !           899:     fprintf(fp, " \"%s\"\n", conv_text(str, timelabel.font));
        !           900:
        !           901:     save_range(fp, R_AXIS, rmin, rmax, autoscale_r, "r");
        !           902:     save_range(fp, T_AXIS, tmin, tmax, autoscale_t, "t");
        !           903:     save_range(fp, U_AXIS, umin, umax, autoscale_u, "u");
        !           904:     save_range(fp, V_AXIS, vmin, vmax, autoscale_v, "v");
        !           905:
        !           906:     SAVE_XYZLABEL("xlabel", xlabel);
        !           907:     SAVE_XYZLABEL("x2label", x2label);
        !           908:
        !           909:     if (strlen(timefmt)) {
        !           910:        fprintf(fp, "set timefmt \"%s\"\n", conv_text(str, timefmt));
        !           911:     }
        !           912:     save_range(fp, FIRST_X_AXIS, xmin, xmax, autoscale_x, "x");
        !           913:     save_range(fp, SECOND_X_AXIS, x2min, x2max, autoscale_x2, "x2");
        !           914:
        !           915:     SAVE_XYZLABEL("ylabel", ylabel);
        !           916:     SAVE_XYZLABEL("y2label", y2label);
        !           917:
        !           918:     save_range(fp, FIRST_Y_AXIS, ymin, ymax, autoscale_y, "y");
        !           919:     save_range(fp, SECOND_Y_AXIS, y2min, y2max, autoscale_y2, "y2");
        !           920:
        !           921:     SAVE_XYZLABEL("zlabel", zlabel);
        !           922:     save_range(fp, FIRST_Z_AXIS, zmin, zmax, autoscale_z, "z");
        !           923:
        !           924:     fprintf(fp, "set zero %g\n", zero);
        !           925:     fprintf(fp, "set lmargin %d\nset bmargin %d\nset rmargin %d\nset tmargin %d\n",
        !           926:            lmargin, bmargin, rmargin, tmargin);
        !           927:
        !           928:     fprintf(fp, "set locale \"%s\"\n", cur_locale);
        !           929: }
        !           930:
        !           931: static void save_tics(fp, where, axis, tdef, rotate, text)
        !           932: FILE *fp;
        !           933: int where;
        !           934: int axis;
        !           935: struct ticdef *tdef;
        !           936: TBOOLEAN rotate;
        !           937: char *text;
        !           938: {
        !           939:     char str[MAX_LINE_LEN + 1];
        !           940:
        !           941:     if (where == NO_TICS) {
        !           942:        fprintf(fp, "set no%stics\n", text);
        !           943:        return;
        !           944:     }
        !           945:     fprintf(fp, "set %stics %s %smirror %srotate ", text,
        !           946:            (where & TICS_MASK) == TICS_ON_AXIS ? "axis" : "border",
        !           947:            (where & TICS_MIRROR) ? "" : "no", rotate ? "" : "no");
        !           948:     switch (tdef->type) {
        !           949:     case TIC_COMPUTED:{
        !           950:            fputs("autofreq ", fp);
        !           951:            break;
        !           952:        }
        !           953:     case TIC_MONTH:{
        !           954:            fprintf(fp, "\nset %smtics", text);
        !           955:            break;
        !           956:        }
        !           957:     case TIC_DAY:{
        !           958:            fprintf(fp, "\nset %cdtics", axis);
        !           959:            break;
        !           960:        }
        !           961:     case TIC_SERIES:
        !           962:        if (datatype[axis] == TIME) {
        !           963:            if (tdef->def.series.start != -VERYLARGE) {
        !           964:                char fd[26];
        !           965:                gstrftime(fd, 24, timefmt, (double) tdef->def.series.start);
        !           966:                fprintf(fp, "\"%s\",", conv_text(str, fd));
        !           967:            }
        !           968:            fprintf(fp, "%g", tdef->def.series.incr);
        !           969:
        !           970:            if (tdef->def.series.end != VERYLARGE) {
        !           971:                char td[26];
        !           972:                gstrftime(td, 24, timefmt, (double) tdef->def.series.end);
        !           973:                fprintf(fp, ",\"%s\"", conv_text(str, td));
        !           974:            }
        !           975:        } else {                /* !TIME */
        !           976:
        !           977:            if (tdef->def.series.start != -VERYLARGE)
        !           978:                fprintf(fp, "%g,", tdef->def.series.start);
        !           979:            fprintf(fp, "%g", tdef->def.series.incr);
        !           980:            if (tdef->def.series.end != VERYLARGE)
        !           981:                fprintf(fp, ",%g", tdef->def.series.end);
        !           982:        }
        !           983:
        !           984:        break;
        !           985:
        !           986:     case TIC_USER:{
        !           987:            register struct ticmark *t;
        !           988:            int flag_time;
        !           989:            flag_time = (datatype[axis] == TIME);
        !           990:            fputs(" (", fp);
        !           991:            for (t = tdef->def.user; t != NULL; t = t->next) {
        !           992:                if (t->label)
        !           993:                    fprintf(fp, "\"%s\" ", conv_text(str, t->label));
        !           994:                if (flag_time) {
        !           995:                    char td[26];
        !           996:                    gstrftime(td, 24, timefmt, (double) t->position);
        !           997:                    fprintf(fp, "\"%s\"", conv_text(str, td));
        !           998:                } else {
        !           999:                    fprintf(fp, "%g", t->position);
        !          1000:                }
        !          1001:                if (t->next) {
        !          1002:                    fputs(", ", fp);
        !          1003:                }
        !          1004:            }
        !          1005:            fputs(")", fp);
        !          1006:            break;
        !          1007:        }
        !          1008:     }
        !          1009:     putc('\n', fp);
        !          1010: }
        !          1011:
        !          1012: static void save_position(fp, pos)
        !          1013: FILE *fp;
        !          1014: struct position *pos;
        !          1015: {
        !          1016:     static char *msg[] =
        !          1017:     {"first_axes ", "second axes ", "graph ", "screen "};
        !          1018:
        !          1019:     assert(first_axes == 0 && second_axes == 1 && graph == 2 && screen == 3);
        !          1020:
        !          1021:     fprintf(fp, "%s%g, %s%g, %s%g",
        !          1022:            pos->scalex == first_axes ? "" : msg[pos->scalex], pos->x,
        !          1023:            pos->scaley == pos->scalex ? "" : msg[pos->scaley], pos->y,
        !          1024:            pos->scalez == pos->scaley ? "" : msg[pos->scalez], pos->z);
        !          1025: }
        !          1026:
        !          1027: void load_file(fp, name, can_do_args)
        !          1028: FILE *fp;
        !          1029: char *name;
        !          1030: TBOOLEAN can_do_args;
        !          1031: {
        !          1032:     register int len;
        !          1033:
        !          1034:     int start, left;
        !          1035:     int more;
        !          1036:     int stop = FALSE;
        !          1037:
        !          1038:     lf_push(fp);               /* save state for errors and recursion */
        !          1039:     do_load_arg_substitution = can_do_args;
        !          1040:
        !          1041:     if (fp == (FILE *) NULL) {
        !          1042:        /* HBB 980311: alloc() it, to save valuable stack space: */
        !          1043:        char *errbuf = gp_alloc(BUFSIZ, "load_file errorstring");
        !          1044:        (void) sprintf(errbuf, "Cannot open %s file '%s'",
        !          1045:                       can_do_args ? "call" : "load", name);
        !          1046:        os_error(errbuf, c_token);
        !          1047:        free(errbuf);
        !          1048:     } else if (fp == stdin) {
        !          1049:        /* DBT 10-6-98  go interactive if "-" named as load file */
        !          1050:        interactive = TRUE;
        !          1051:        while(!com_line())
        !          1052:            ;
        !          1053:     } else {
        !          1054:        /* go into non-interactive mode during load */
        !          1055:        /* will be undone below, or in load_file_error */
        !          1056:        interactive = FALSE;
        !          1057:        inline_num = 0;
        !          1058:        infile_name = name;
        !          1059:
        !          1060:        if (can_do_args) {
        !          1061:            int aix = 0;
        !          1062:            while (++c_token < num_tokens && aix <= 9) {
        !          1063:                if (isstring(c_token))
        !          1064:                    m_quote_capture(&call_args[aix++], c_token, c_token);
        !          1065:                else
        !          1066:                    m_capture(&call_args[aix++], c_token, c_token);
        !          1067:            }
        !          1068:
        !          1069: /*         A GNUPLOT "call" command can have up to _10_ arguments named "$0"
        !          1070:    to "$9".  After reading the 10th argument (i.e.: "$9") the variable
        !          1071:    'aix' contains the value '10' because of the 'aix++' construction
        !          1072:    in '&call_args[aix++]'.  So I think the following test of 'aix'
        !          1073:    should be done against '10' instead of '9'.                (JFi) */
        !          1074:
        !          1075: /*              if (c_token >= num_tokens && aix > 9) */
        !          1076:            if (c_token >= num_tokens && aix > 10)
        !          1077:                int_error("too many arguments for CALL <file>", ++c_token);
        !          1078:        }
        !          1079:        while (!stop) {         /* read all commands in file */
        !          1080:            /* read one command */
        !          1081:            left = input_line_len;
        !          1082:            start = 0;
        !          1083:            more = TRUE;
        !          1084:
        !          1085:            while (more) {
        !          1086:                if (fgets(&(input_line[start]), left, fp) == (char *) NULL) {
        !          1087:                    stop = TRUE;        /* EOF in file */
        !          1088:                    input_line[start] = '\0';
        !          1089:                    more = FALSE;
        !          1090:                } else {
        !          1091:                    inline_num++;
        !          1092:                    len = strlen(input_line) - 1;
        !          1093:                    if (input_line[len] == '\n') {      /* remove any newline */
        !          1094:                        input_line[len] = '\0';
        !          1095:                        /* Look, len was 1-1 = 0 before, take care here! */
        !          1096:                        if (len > 0)
        !          1097:                            --len;
        !          1098:                        if (input_line[len] == '\r') {  /* remove any carriage return */
        !          1099:                            input_line[len] = NUL;
        !          1100:                            if (len > 0)
        !          1101:                                --len;
        !          1102:                        }
        !          1103:                    }
        !          1104:                     else if (len + 2 >= left) {
        !          1105:                        extend_input_line();
        !          1106:                        left = input_line_len - len - 1;
        !          1107:                        start = len + 1;
        !          1108:                        continue;       /* don't check for '\' */
        !          1109:                    }
        !          1110:                    if (input_line[len] == '\\') {
        !          1111:                        /* line continuation */
        !          1112:                        start = len;
        !          1113:                        left = input_line_len - start;
        !          1114:                    } else
        !          1115:                        more = FALSE;
        !          1116:                }
        !          1117:            }
        !          1118:
        !          1119:            if (strlen(input_line) > 0) {
        !          1120:                if (can_do_args) {
        !          1121:                    register int il = 0;
        !          1122:                    register char *rl;
        !          1123:                    char *raw_line = rl = gp_alloc((unsigned long) strlen(input_line) + 1, "string");
        !          1124:
        !          1125:                    strcpy(raw_line, input_line);
        !          1126:                    *input_line = '\0';
        !          1127:                    while (*rl) {
        !          1128:                        register int aix;
        !          1129:                        if (*rl == '$'
        !          1130:                            && ((aix = *(++rl)) != 0)   /* HBB 980308: quiet BCC warning */
        !          1131:                            &&aix >= '0' && aix <= '9') {
        !          1132:                            if (call_args[aix -= '0']) {
        !          1133:                                len = strlen(call_args[aix]);
        !          1134:                                while (input_line_len - il < len + 1) {
        !          1135:                                    extend_input_line();
        !          1136:                                }
        !          1137:                                strcpy(input_line + il, call_args[aix]);
        !          1138:                                il += len;
        !          1139:                            }
        !          1140:                        } else {
        !          1141:                            /* substitute for $<n> here */
        !          1142:                            if (il + 1 > input_line_len) {
        !          1143:                                extend_input_line();
        !          1144:                            }
        !          1145:                            input_line[il++] = *rl;
        !          1146:                        }
        !          1147:                        rl++;
        !          1148:                    }
        !          1149:                    if (il + 1 > input_line_len) {
        !          1150:                        extend_input_line();
        !          1151:                    }
        !          1152:                    input_line[il] = '\0';
        !          1153:                    free(raw_line);
        !          1154:                }
        !          1155:                screen_ok = FALSE;      /* make sure command line is
        !          1156:                                           echoed on error */
        !          1157:                do_line();
        !          1158:            }
        !          1159:        }
        !          1160:     }
        !          1161:
        !          1162:     /* pop state */
        !          1163:     (void) lf_pop();           /* also closes file fp */
        !          1164: }
        !          1165:
        !          1166: /* pop from load_file state stack */
        !          1167: static TBOOLEAN                        /* FALSE if stack was empty */
        !          1168:  lf_pop()
        !          1169: {                              /* called by load_file and load_file_error */
        !          1170:     LFS *lf;
        !          1171:
        !          1172:     if (lf_head == NULL)
        !          1173:        return (FALSE);
        !          1174:     else {
        !          1175:        int argindex;
        !          1176:        lf = lf_head;
        !          1177:        if (lf->fp != (FILE *)NULL && lf->fp != stdin) {
        !          1178:            /* DBT 10-6-98  do not close stdin in the case
        !          1179:             * that "-" is named as a load file
        !          1180:             */
        !          1181:            (void) fclose(lf->fp);
        !          1182:        }
        !          1183:        for (argindex = 0; argindex < 10; argindex++) {
        !          1184:            if (call_args[argindex]) {
        !          1185:                free(call_args[argindex]);
        !          1186:            }
        !          1187:            call_args[argindex] = lf->call_args[argindex];
        !          1188:        }
        !          1189:        do_load_arg_substitution = lf->do_load_arg_substitution;
        !          1190:        interactive = lf->interactive;
        !          1191:        inline_num = lf->inline_num;
        !          1192:        infile_name = lf->name;
        !          1193:        lf_head = lf->prev;
        !          1194:        free((char *) lf);
        !          1195:        return (TRUE);
        !          1196:     }
        !          1197: }
        !          1198:
        !          1199: /* push onto load_file state stack */
        !          1200: /* essentially, we save information needed to undo the load_file changes */
        !          1201: static void lf_push(fp)                /* called by load_file */
        !          1202: FILE *fp;
        !          1203: {
        !          1204:     LFS *lf;
        !          1205:     int argindex;
        !          1206:
        !          1207:     lf = (LFS *) gp_alloc((unsigned long) sizeof(LFS), (char *) NULL);
        !          1208:     if (lf == (LFS *) NULL) {
        !          1209:        if (fp != (FILE *) NULL)
        !          1210:            (void) fclose(fp);  /* it won't be otherwise */
        !          1211:        int_error("not enough memory to load file", c_token);
        !          1212:     }
        !          1213:     lf->fp = fp;               /* save this file pointer */
        !          1214:     lf->name = infile_name;    /* save current name */
        !          1215:     lf->interactive = interactive;     /* save current state */
        !          1216:     lf->inline_num = inline_num;       /* save current line number */
        !          1217:     lf->do_load_arg_substitution = do_load_arg_substitution;
        !          1218:     for (argindex = 0; argindex < 10; argindex++) {
        !          1219:        lf->call_args[argindex] = call_args[argindex];
        !          1220:        call_args[argindex] = NULL;     /* initially no args */
        !          1221:     }
        !          1222:     lf->prev = lf_head;                /* link to stack */
        !          1223:     lf_head = lf;
        !          1224: }
        !          1225:
        !          1226: /* used for reread  vsnyder@math.jpl.nasa.gov */
        !          1227: FILE *lf_top()
        !          1228: {
        !          1229:     if (lf_head == (LFS *) NULL)
        !          1230:        return ((FILE *) NULL);
        !          1231:     return (lf_head->fp);
        !          1232: }
        !          1233:
        !          1234: /* called from main */
        !          1235: void load_file_error()
        !          1236: {
        !          1237:     /* clean up from error in load_file */
        !          1238:     /* pop off everything on stack */
        !          1239:     while (lf_pop());
        !          1240: }
        !          1241:
        !          1242: /* find char c in string str; return p such that str[p]==c;
        !          1243:  * if c not in str then p=strlen(str)
        !          1244:  */
        !          1245: int instring(str, c)
        !          1246: char *str;
        !          1247: int c;
        !          1248: {
        !          1249:     int pos = 0;
        !          1250:
        !          1251:     while (str != NULL && *str != NUL && c != *str) {
        !          1252:        str++;
        !          1253:        pos++;
        !          1254:     }
        !          1255:     return (pos);
        !          1256: }
        !          1257:
        !          1258: void show_functions()
        !          1259: {
        !          1260:     register struct udft_entry *udf = first_udf;
        !          1261:
        !          1262:     fputs("\n\tUser-Defined Functions:\n", stderr);
        !          1263:
        !          1264:     while (udf) {
        !          1265:        if (udf->definition)
        !          1266:            fprintf(stderr, "\t%s\n", udf->definition);
        !          1267:        else
        !          1268:            fprintf(stderr, "\t%s is undefined\n", udf->udf_name);
        !          1269:        udf = udf->next_udf;
        !          1270:     }
        !          1271: }
        !          1272:
        !          1273:
        !          1274: void show_at()
        !          1275: {
        !          1276:     (void) putc('\n', stderr);
        !          1277:     disp_at(temp_at(), 0);
        !          1278: }
        !          1279:
        !          1280:
        !          1281: void disp_at(curr_at, level)
        !          1282: struct at_type *curr_at;
        !          1283: int level;
        !          1284: {
        !          1285:     register int i, j;
        !          1286:     register union argument *arg;
        !          1287:
        !          1288:     for (i = 0; i < curr_at->a_count; i++) {
        !          1289:        (void) putc('\t', stderr);
        !          1290:        for (j = 0; j < level; j++)
        !          1291:            (void) putc(' ', stderr);   /* indent */
        !          1292:
        !          1293:        /* print name of instruction */
        !          1294:
        !          1295:        fputs(ft[(int) (curr_at->actions[i].index)].f_name, stderr);
        !          1296:        arg = &(curr_at->actions[i].arg);
        !          1297:
        !          1298:        /* now print optional argument */
        !          1299:
        !          1300:        switch (curr_at->actions[i].index) {
        !          1301:        case PUSH:
        !          1302:            fprintf(stderr, " %s\n", arg->udv_arg->udv_name);
        !          1303:            break;
        !          1304:        case PUSHC:
        !          1305:            (void) putc(' ', stderr);
        !          1306:            disp_value(stderr, &(arg->v_arg));
        !          1307:            (void) putc('\n', stderr);
        !          1308:            break;
        !          1309:        case PUSHD1:
        !          1310:            fprintf(stderr, " %c dummy\n",
        !          1311:                    arg->udf_arg->udf_name[0]);
        !          1312:            break;
        !          1313:        case PUSHD2:
        !          1314:            fprintf(stderr, " %c dummy\n",
        !          1315:                    arg->udf_arg->udf_name[1]);
        !          1316:            break;
        !          1317:        case CALL:
        !          1318:            fprintf(stderr, " %s", arg->udf_arg->udf_name);
        !          1319:            if (level < 6) {
        !          1320:                if (arg->udf_arg->at) {
        !          1321:                    (void) putc('\n', stderr);
        !          1322:                    disp_at(arg->udf_arg->at, level + 2);       /* recurse! */
        !          1323:                } else
        !          1324:                    fputs(" (undefined)\n", stderr);
        !          1325:            } else
        !          1326:                (void) putc('\n', stderr);
        !          1327:            break;
        !          1328:        case CALLN:
        !          1329:            fprintf(stderr, " %s", arg->udf_arg->udf_name);
        !          1330:            if (level < 6) {
        !          1331:                if (arg->udf_arg->at) {
        !          1332:                    (void) putc('\n', stderr);
        !          1333:                    disp_at(arg->udf_arg->at, level + 2);       /* recurse! */
        !          1334:                } else
        !          1335:                    fputs(" (undefined)\n", stderr);
        !          1336:            } else
        !          1337:                (void) putc('\n', stderr);
        !          1338:            break;
        !          1339:        case JUMP:
        !          1340:        case JUMPZ:
        !          1341:        case JUMPNZ:
        !          1342:        case JTERN:
        !          1343:            fprintf(stderr, " +%d\n", arg->j_arg);
        !          1344:            break;
        !          1345:        case DOLLARS:
        !          1346:            fprintf(stderr, " %d\n", arg->v_arg.v.int_val);
        !          1347:            break;
        !          1348:        default:
        !          1349:            (void) putc('\n', stderr);
        !          1350:        }
        !          1351:     }
        !          1352: }
        !          1353:
        !          1354: /* find max len of keys and count keys with len > 0 */
        !          1355:
        !          1356: int find_maxl_keys(plots, count, kcnt)
        !          1357: struct curve_points *plots;
        !          1358: int count, *kcnt;
        !          1359: {
        !          1360:     int mlen, len, curve, cnt;
        !          1361:     register struct curve_points *this_plot;
        !          1362:
        !          1363:     mlen = cnt = 0;
        !          1364:     this_plot = plots;
        !          1365:     for (curve = 0; curve < count; this_plot = this_plot->next_cp, curve++)
        !          1366:        if (this_plot->title
        !          1367:            && ((len = /*assign */ strlen(this_plot->title)) != 0)      /* HBB 980308: quiet BCC warning */
        !          1368:            ) {
        !          1369:            cnt++;
        !          1370:            if (len > mlen)
        !          1371:                mlen = strlen(this_plot->title);
        !          1372:        }
        !          1373:     if (kcnt != NULL)
        !          1374:        *kcnt = cnt;
        !          1375:     return (mlen);
        !          1376: }
        !          1377:
        !          1378:
        !          1379: /* calculate the number and max-width of the keys for an splot.
        !          1380:  * Note that a blank line is issued after each set of contours
        !          1381:  */
        !          1382: int find_maxl_keys3d(plots, count, kcnt)
        !          1383: struct surface_points *plots;
        !          1384: int count, *kcnt;
        !          1385: {
        !          1386:     int mlen, len, surf, cnt;
        !          1387:     struct surface_points *this_plot;
        !          1388:
        !          1389:     mlen = cnt = 0;
        !          1390:     this_plot = plots;
        !          1391:     for (surf = 0; surf < count; this_plot = this_plot->next_sp, surf++) {
        !          1392:
        !          1393:        /* we draw a main entry if there is one, and we are
        !          1394:         * drawing either surface, or unlabelled contours
        !          1395:         */
        !          1396:        if (this_plot->title && *this_plot->title &&
        !          1397:            (draw_surface || (draw_contour && !label_contours))) {
        !          1398:            ++cnt;
        !          1399:            len = strlen(this_plot->title);
        !          1400:            if (len > mlen)
        !          1401:                mlen = len;
        !          1402:        }
        !          1403:        if (draw_contour && label_contours && this_plot->contours != NULL) {
        !          1404:            len = find_maxl_cntr(this_plot->contours, &cnt);
        !          1405:            if (len > mlen)
        !          1406:                mlen = len;
        !          1407:        }
        !          1408:     }
        !          1409:
        !          1410:     if (kcnt != NULL)
        !          1411:        *kcnt = cnt;
        !          1412:     return (mlen);
        !          1413: }
        !          1414:
        !          1415: static int find_maxl_cntr(contours, count)
        !          1416: struct gnuplot_contours *contours;
        !          1417: int *count;
        !          1418: {
        !          1419:     register int cnt;
        !          1420:     register int mlen, len;
        !          1421:     register struct gnuplot_contours *cntrs = contours;
        !          1422:
        !          1423:     mlen = cnt = 0;
        !          1424:     while (cntrs) {
        !          1425:        if (label_contours && cntrs->isNewLevel) {
        !          1426:            len = strlen(cntrs->label);
        !          1427:            if (len)
        !          1428:                cnt++;
        !          1429:            if (len > mlen)
        !          1430:                mlen = len;
        !          1431:        }
        !          1432:        cntrs = cntrs->next;
        !          1433:     }
        !          1434:     *count += cnt;
        !          1435:     return (mlen);
        !          1436: }
        !          1437:
        !          1438: static void save_range(fp, axis, min, max, autosc, text)
        !          1439: FILE *fp;
        !          1440: int axis;
        !          1441: double min, max;
        !          1442: TBOOLEAN autosc;
        !          1443: char *text;
        !          1444: {
        !          1445:     int i;
        !          1446:
        !          1447:     i = axis;
        !          1448:     fprintf(fp, "set %srange [ ", text);
        !          1449:     if (autosc & 1) {
        !          1450:        putc('*', fp);
        !          1451:     } else {
        !          1452:        SAVE_NUM_OR_TIME(fp, min, axis);
        !          1453:     }
        !          1454:     fputs(" : ", fp);
        !          1455:     if (autosc & 2) {
        !          1456:        putc('*', fp);
        !          1457:     } else {
        !          1458:        SAVE_NUM_OR_TIME(fp, max, axis);
        !          1459:     }
        !          1460:
        !          1461:     fprintf(fp, " ] %sreverse %swriteback",
        !          1462:            range_flags[axis] & RANGE_REVERSE ? "" : "no",
        !          1463:            range_flags[axis] & RANGE_WRITEBACK ? "" : "no");
        !          1464:
        !          1465:     if (autosc) {
        !          1466:        /* add current (hidden) range as comments */
        !          1467:        fputs("  # (currently [", fp);
        !          1468:        if (autosc & 1) {
        !          1469:            SAVE_NUM_OR_TIME(fp, min, axis);
        !          1470:        }
        !          1471:        putc(':', fp);
        !          1472:        if (autosc & 2) {
        !          1473:            SAVE_NUM_OR_TIME(fp, max, axis);
        !          1474:        }
        !          1475:        fputs("] )", fp);
        !          1476:     }
        !          1477:     putc('\n', fp);
        !          1478: }
        !          1479:
        !          1480: /* check user defined format strings for valid double conversions */
        !          1481: TBOOLEAN valid_format(format)
        !          1482: const char *format;
        !          1483: {
        !          1484:     for (;;) {
        !          1485:        if (!(format = strchr(format, '%')))    /* look for format spec  */
        !          1486:            return TRUE;        /* passed Test           */
        !          1487:        do {                    /* scan format statement */
        !          1488:            format++;
        !          1489:        } while (strchr("+-#0123456789.", *format));
        !          1490:
        !          1491:        switch (*format) {      /* Now at format modifier */
        !          1492:        case '*':               /* Ignore '*' statements */
        !          1493:        case '%':               /* Char   '%' itself     */
        !          1494:            format++;
        !          1495:            continue;
        !          1496:        case 'l':               /* Now we found it !!! */
        !          1497:            if (!strchr("fFeEgG", format[1]))   /* looking for a valid format */
        !          1498:                return FALSE;
        !          1499:            format++;
        !          1500:            break;
        !          1501:        default:
        !          1502:            return FALSE;
        !          1503:        }
        !          1504:     }
        !          1505: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>