home *** CD-ROM | disk | FTP | other *** search
/ Photo CD Demo 1 / Demo.bin / gle / gle / menu.c < prev    next >
C/C++ Source or Header  |  1992-11-29  |  34KB  |  1,362 lines

  1. #include "all.h"
  2. #include "color.h"
  3. #include "edt.h"
  4. #ifdef unix
  5. #define SEEK_SET 0
  6. #endif
  7.  
  8. #ifdef __TURBOC__
  9. #define DASHCHAR 249
  10. #include "bios.h"
  11. #include "conio.h"
  12. #include "dir.h"
  13. #else
  14. #define DASHCHAR '.'
  15. #include "vaxconio.h"
  16. #endif
  17.  
  18. #define true (!false)
  19. #define false 0
  20. #define BEGINDEF extern
  21. #include "begin.h"
  22. #define BCOLOR BLUE
  23. #define FCOLOR MAGENTA
  24. #define HBCOLOR h_bcolor
  25. #define HVCOLOR h_fcolor
  26. #define VCOLOR WHITE
  27.  
  28. int h_bcolor;
  29. int h_fcolor;
  30. int getsize(void);
  31. char *tabtospace(char *s);
  32. int printdash(int i);
  33. char *gledir(char *s);
  34. int scr_menuval(void);
  35. int scr_menubg(void);
  36. int scr_menuhi(void);
  37. int scr_grey(void);
  38. int gle_redraw(void);
  39. int text_showerror(void);
  40. int text_save(void);
  41. int fner(char *s);
  42. char *strfile(char *s);
  43.  
  44. int vdelete(int i);
  45. int vinsert(int y, char *s);
  46. int m_ifsend(char *s);
  47. int m_sendline(void);
  48. int minit_extras(void);
  49. int minit_extras(void);
  50. int initmenu(void);
  51. int mystrlen(char *s);
  52. int pick_file(char *d, char *w);
  53. int ncpy(char *d, char *s, int n);
  54. int setvstr(char **d, char *s);
  55. int do_help(char *s);
  56. int text_inkey(void);
  57.  
  58. extern int ngtxt;
  59. extern char *(*gtxt)[];
  60.  
  61.  
  62. struct menu_struct { int x; int y; char *title; int width; int typ; int typ2;
  63.     char *val; char *help; };
  64. typedef struct menu_struct menutype;
  65. struct pmenu_struct {int ci; menutype *menu; };
  66. typedef struct pmenu_struct pmenutype;
  67. pmenutype pmenu[17];
  68. int setmenu(menutype *m,int x, int y, int typ, int typ2, int width, char *title
  69.     , char *val, char *help);
  70. int do_menu(pmenutype *p);
  71. int token_space(void);
  72. int extractmenu(void);
  73. int add_unrecognized(char *s);
  74. int fillinmenu(int nbegin);
  75. int nunrec;
  76.  
  77. #define  PTXT 0
  78. enum {MEND,MTEXT,MFILE,MTOGON,MTOGOFF,MSUB,MRETURN,MNULL};
  79. enum {SNORM,SROL,SNEXTS,SNEXT,SSTR,STOG,SS,SSIZE,SNOBOX,SAMOVE,SSOFF,SSNULL};
  80. menutype xnamesmenu[] = {
  81.     2,3,    "Xnames ",    64,MTEXT,SROL,PTXT,"xnames",
  82.     2,5,    "Xplaces ",    64,MTEXT,SROL,PTXT,"xplaces",
  83.     0,0,"",            0,MEND,0,0,""};
  84. menutype ynamesmenu[] = {
  85.     2,3,    "Ynames ",    64,MTEXT,SROL,PTXT,"ynames",
  86.     2,5,    "Yplaces ",    64,MTEXT,SROL,PTXT,"yplaces",
  87.     0,0,"",            0,MEND,0,0,""};
  88. menutype x2namesmenu[] = {
  89.     2,3,    "X2names ",    64,MTEXT,SROL,PTXT,"x2names",
  90.     2,5,    "X2places ",    64,MTEXT,SROL,PTXT,"x2places",
  91.     0,0,"",            0,MEND,0,0,""};
  92. menutype y2namesmenu[] = {
  93.     2,3,    "Y2names ",    64,MTEXT,SROL,PTXT,"y2names",
  94.     2,5,    "Y2places ",    64,MTEXT,SROL,PTXT,"y2places",
  95.     0,0,"",            0,MEND,0,0,""};
  96. menutype x2axismenu[] = {
  97.  
  98.     1,4,    "X2Title ",    27,MTEXT,SNEXTS,PTXT,"x2title",
  99.     37,4,    "Hei ",        4,MTEXT,0,PTXT,"x2title hei",
  100.     46,4,    "Dist ",    3,MTEXT,0,PTXT,"x2title dist",
  101.     55,4,    "Font " ,    4,MTEXT,0,PTXT,"x2title font",
  102.     65,4,    "Color ",    7,MTEXT,0,PTXT,"x2title color",
  103.  
  104.     1,6,    "X2axis ",    3,MTOGON,SSOFF,PTXT,"x2axis off",
  105.     13,6,    "Min ",        6,MTEXT,0,PTXT,"x2axis min",
  106.     24,6,    "Max ",        6,MTEXT,0,PTXT,"x2axis max",
  107.     35,6,    "Dticks ",    6,MTEXT,0,PTXT,"x2axis dticks",
  108.     49,6,    "Dsubticks ",    6,MTEXT,0,PTXT,"x2axis dsubticks",
  109.     66,6,    "LOG ",        3,MTOGOFF,SS,PTXT,"x2axis log",
  110.  
  111.     1,8,    "X2labels ",    3,MTOGOFF,SS,PTXT,"x2labels on",
  112.     15,8,    "Hei ",        4,MTEXT,0,PTXT,"x2labels hei",
  113.     24,8,    "Dist ",    4,MTEXT,0,PTXT,"x2labels dist",
  114.     34,8,    "Font ",    4,MTEXT,0,PTXT,"x2labels font",
  115.     44,8,    "Color ",    7,MTEXT,0,PTXT,"x2labels color",
  116.     59,8,    "",        5,MSUB,103,"Names","x2names",
  117.     0,0,"",            0,MEND,0,0,""};
  118.  
  119. menutype y2axismenu[] = {
  120.  
  121.     1,4,    "Y2Title ",    27,MTEXT,SNEXTS,PTXT,"y2title",
  122.     37,4,    "Hei ",        4,MTEXT,0,PTXT,"y2title hei",
  123.     46,4,    "Dist ",    3,MTEXT,0,PTXT,"y2title dist",
  124.     55,4,    "Font " ,    4,MTEXT,0,PTXT,"y2title font",
  125.     65,4,    "Color ",    7,MTEXT,0,PTXT,"y2title color",
  126.  
  127.  
  128.     1,6,    "Y2axis ",    3,MTOGON,SSOFF,PTXT,"y2axis off",
  129.     12,6,    "Min ",        6,MTEXT,0,PTXT,"y2axis min",
  130.     23,6,    "Max ",        6,MTEXT,0,PTXT,"y2axis max",
  131.     34,6,    "Dticks ",    6,MTEXT,0,PTXT,"y2axis dticks",
  132.     48,6,    "Dsubticks ",    6,MTEXT,0,PTXT,"y2axis dsubticks",
  133.     65,6,    "LOG ",        3,MTOGOFF,SS,PTXT,"y2axis log",
  134.  
  135.     1,8,    "Y2labels ",    3,MTOGOFF,SS,PTXT,"y2labels on",
  136.     15,8,    "Hei ",        4,MTEXT,0,PTXT,"y2labels hei",
  137.     24,8,    "Dist ",    4,MTEXT,0,PTXT,"y2labels dist",
  138.     34,8,    "Font ",    4,MTEXT,0,PTXT,"y2labels font",
  139.     44,8,    "Color ",    7,MTEXT,0,PTXT,"y2labels color",
  140.     59,8,    "",        4,MSUB,104,"Names","y2names",
  141.     0,0,"",            0,MEND,0,0,""};
  142. menutype fillmenu[] = {
  143.     2,3,    "Fill ",    60,MTEXT,SROL,PTXT,"fill",
  144.     2,5,    "Fill ",    60,MTEXT,SROL,PTXT,"fill",
  145.     2,7,    "Fill ",    60,MTEXT,SROL,PTXT,"fill",
  146.     2,9,    "Fill ",    60,MTEXT,SROL,PTXT,"fill",
  147.     2,11,    "Fill ",    60,MTEXT,SROL,PTXT,"fill",
  148.     0,0,"",            0,MEND,0,0,""};
  149. menutype barmenu[] = {
  150.     2,3,    "Bar ",        60,MTEXT,SROL,PTXT,"bar",
  151.     2,5,    "Bar ",        60,MTEXT,SROL,PTXT,"bar",
  152.     2,7,    "Bar ",        60,MTEXT,SROL,PTXT,"bar",
  153.     2,9,    "Bar ",        60,MTEXT,SROL,PTXT,"bar",
  154.     2,11,    "Bar ",        60,MTEXT,SROL,PTXT,"bar",
  155.     0,0,"",            0,MEND,0,0,""};
  156. menutype letmenu[] = {
  157.     2,3,    "Let ",        60,MTEXT,SROL,PTXT,"let",
  158.     2,5,    "Let ",        60,MTEXT,SROL,PTXT,"let",
  159.     2,7,    "Let ",        60,MTEXT,SROL,PTXT,"let",
  160.     2,9,    "Let ",        60,MTEXT,SROL,PTXT,"let",
  161.     2,11,    "Let ",        60,MTEXT,SROL,PTXT,"let",
  162.     0,0,"",            0,MEND,0,0,""};
  163. menutype xtramenu[] = {
  164.     2,3,    "Xtra ",        60,MTEXT,SROL,PTXT,"xtra",
  165.     2,5,    "Xtra ",        60,MTEXT,SROL,PTXT,"xtra",
  166.     2,7,    "Xtra ",        60,MTEXT,SROL,PTXT,"xtra",
  167.     2,9,    "Xtra ",        60,MTEXT,SROL,PTXT,"xtra",
  168.     2,11,    "Xtra ",        60,MTEXT,SROL,PTXT,"xtra",
  169.     0,0,"",            0,MEND,0,0,""};
  170. /* int x; int y; char *title; int width; int typ; int typ2; char *val; */
  171. menutype graphmenu[278] = {
  172.     1,1,    "Size ",    4,MTEXT,SSIZE,"24","size",
  173.     12,1,    "",        4,MTEXT,0,"18","size",
  174.     19,1,    "Position ",    4,MTEXT,SAMOVE,PTXT,"position",
  175.     34,1,    "",        4,MTEXT,SAMOVE,PTXT,"position",
  176. /*    42,1,    "Lwidth ",    4,MTEXT,0,PTXT,"lwidth", */
  177.     55,1,    "Border ",    3,MTOGON,SNOBOX,PTXT,"nobox",
  178.  
  179.     1,2,    "Title ",    27,MTEXT,SNEXTS,PTXT,"title",
  180.     37,2,    "Hei ",        4,MTEXT,0,PTXT,"title hei",
  181.     46,2,    "Dist ",    3,MTEXT,0,PTXT,"title dist",
  182.     55,2,    "Font " ,    4,MTEXT,0,PTXT,"title font",
  183.     65,2,    "Color ",    7,MTEXT,0,PTXT,"title color",
  184.  
  185.     1,3,    "XTitle ",    27,MTEXT,SNEXTS,PTXT,"xtitle",
  186.     37,3,    "Hei ",        4,MTEXT,0,PTXT,"xtitle hei",
  187.     46,3,    "Dist ",    3,MTEXT,0,PTXT,"xtitle dist",
  188.     55,3,    "Font " ,    4,MTEXT,0,PTXT,"xtitle font",
  189.     65,3,    "Color ",    7,MTEXT,0,PTXT,"xtitle color",
  190.  
  191.     1,4,    "YTitle ",    27,MTEXT,SNEXTS,PTXT,"ytitle",
  192.     37,4,    "Hei ",        4,MTEXT,0,PTXT,"ytitle hei",
  193.     46,4,    "Dist ",    3,MTEXT,0,PTXT,"ytitle dist",
  194.     55,4,    "Font " ,    4,MTEXT,0,PTXT,"ytitle font",
  195.     65,4,    "Color ",    7,MTEXT,0,PTXT,"ytitle color",
  196.  
  197.     1,5,    "Xaxis ",    3,MTOGON,SSOFF,PTXT,"xaxis off",
  198.     12,5,    "Min ",        6,MTEXT,0,PTXT,"xaxis min",
  199.     23,5,    "Max ",        6,MTEXT,0,PTXT,"xaxis max",
  200.     34,5,    "Dticks ",    6,MTEXT,0,PTXT,"xaxis dticks",
  201.     48,5,    "Dsubticks ",    6,MTEXT,0,PTXT,"xaxis dsubticks",
  202.     65,5,    "LOG ",        3,MTOGOFF,SS,PTXT,"xaxis log",
  203.  
  204.     1,6,    "Yaxis ",    3,MTOGON,SSOFF,PTXT,"yaxis off",
  205.     12,6,    "Min ",        6,MTEXT,0,PTXT,"yaxis min",
  206.     23,6,    "Max ",        6,MTEXT,0,PTXT,"yaxis max",
  207.     34,6,    "Dticks ",    6,MTEXT,0,PTXT,"yaxis dticks",
  208.     48,6,    "Dsubticks ",    6,MTEXT,0,PTXT,"yaxis dsubticks",
  209.     65,6,    "LOG ",        3,MTOGOFF,SS,PTXT,"yaxis log",
  210.  
  211.     1,7,    "Xlabels ",    3,MTOGON,SSOFF,PTXT,"xlabels off",
  212.     14,7,    "Hei ",        4,MTEXT,0,PTXT,"xlabels hei",
  213.     23,7,    "Dist ",    4,MTEXT,0,PTXT,"xlabels dist",
  214.     33,7,    "Font ",    4,MTEXT,0,PTXT,"xlabels font",
  215.     43,7,    "Color ",    7,MTEXT,0,PTXT,"xlabels color",
  216.     58,7,    "",        6,MSUB,101,"Xnames","xnames",
  217.     66,7,    "Grid ",    3,MTOGOFF,SS,PTXT,"xaxis grid",
  218.  
  219.     1,8,    "Ylabels ",    3,MTOGON,SSOFF,PTXT,"ylabels off",
  220.     14,8,    "Hei ",        4,MTEXT,0,PTXT,"ylabels hei",
  221.     23,8,    "Dist ",    4,MTEXT,0,PTXT,"ylabels dist",
  222.     33,8,    "Font ",    4,MTEXT,0,PTXT,"ylabels font",
  223.     43,8,    "Color ",    7,MTEXT,0,PTXT,"ylabels color",
  224.     58,8,    "",        6,MSUB,102,"Ynames","ynames",
  225.     66,8,    "Grid ",    3,MTOGOFF,SS,PTXT,"yaxis grid",
  226.  
  227.     1,10,    "",        6,MSUB,105,"X2axis","x2axis",
  228.     16,10,    "",        6,MSUB,106,"Y2axis","y2axis",
  229.     31,10,    "",        3,MSUB,108,"Bar","bar",
  230.     46,10,    "",        4,MSUB,107,"Fill","fill",
  231.     61,10,    "",        3,MSUB,109,"Let","let",
  232.     70,10,    "",        6,MSUB,110,"Xtra's","xtra",
  233.  
  234.     1,12,    "Data Files",    0,MNULL,0,PTXT,"",
  235.     23,12,    "Dn Marker    Lstyle Color Lwidth Smooth  Keytext     Err",
  236.                 0,MNULL,0,PTXT,"",
  237.     0,0,"",            0,MEND,0,0,""
  238. };
  239. int refresh_menu(struct menu_struct *m);
  240. int menu_hilight(struct menu_struct *m);
  241. int menu_norm(struct menu_struct *m);
  242.  
  243. /* menu's
  244.     topmenu
  245.         title,xtitle,ytitle min max dist on off, ticks dticks
  246.         (2) let d = exp
  247.         Data files
  248.         Dn marker ,color, lwidth, lstyle, err,
  249.     xnamesmenu
  250.     ynamesmenu
  251.     fillmenu
  252.     barmenu
  253.     axismenu's
  254. */
  255. read_default(char *result, char *ques, char *dflt)
  256. {
  257.     char s[200];
  258.     int r;
  259.     strcpy(s,ques); strcat(s," ["); strcat(s,dflt); strcat(s,"] ");
  260.     r = read_input(result,s);
  261.     if (strlen(result)==0) strcpy(result,dflt);
  262.     return r;
  263. }
  264. extern int changed;
  265. addline(char *s)
  266. {
  267.     changed = true;
  268.     vinsert(ngtxt+1,s);
  269. }
  270. char *mark_names[] = {
  271.     "dot", "square", "fcircle", "club", "diamond", "triangle", "snake"
  272.     ,"otimes", "odot", ""};
  273.  
  274. idiot_questions()
  275. {
  276.     char s1[80],ss1[60],ss2[60],ss[100];
  277.     char s2[80];
  278.     int m,i,nd,domark;
  279.  
  280.     scr_norm();
  281.     window(1,1,80,25);
  282.     clrscr();
  283.     gotoxy(1,1);
  284. /*    scr_menuval(); */
  285.  
  286. #define dflt(v1,v2,v3) if (read_default(v1,v2,v3)) goto abort_idiot
  287.  
  288.     addline("amove 0 0");
  289.     addline("begin graph");
  290.     wprintf("    Answer the following questions to set up a simple graph\n");
  291.     wprintf("    (press return for defaults)\n\n");
  292.     dflt(s1,"Width of graph in cm","24");
  293.     dflt(s2,"Height of graph in cm","18");
  294.     sprintf(ss,"    size %s %s",s1,s2); addline(ss);
  295.     dflt(s1,"How many data files do you have to graph","1");
  296.     nd = atoi(s1);
  297.     for (i=0;i<nd; i++) {
  298.         dflt(s1,"Name of data file","*.dat"); strcpy(s2,s1);
  299.         if (strchr(s1,'*')!=NULL)  {
  300.             screen_save();
  301.             pick_file(s2,s1);
  302.             screen_restore();
  303.         }
  304.         sprintf(ss,"    data %s",s2); addline(ss);
  305.     }
  306.     dflt(s1,"Xaxis min","auto-scale");
  307.     dflt(s2,"Xaxis max","auto-scale");
  308.     ss1[0] = 0; ss2[0] = 0;
  309.     if (strcmp(s1,"auto-scale")!=0) sprintf(ss1,"min %s ",s1);
  310.     if (strcmp(s2,"auto-scale")!=0) sprintf(ss2,"max %s ",s2);
  311.     sprintf(ss,"    xaxis %s %s ",ss1,ss2); addline(ss);
  312.  
  313.     dflt(s1,"Yaxis min","auto-scale");
  314.     dflt(s2,"Yaxis max","auto-scale");
  315.     ss1[0] = 0; ss2[0] = 0;
  316.     if (strcmp(s1,"auto-scale")!=0) sprintf(ss1,"min %s ",s1);
  317.     if (strcmp(s2,"auto-scale")!=0) sprintf(ss2,"max %s ",s2);
  318.     sprintf(ss,"    yaxis %s %s ",ss1,ss2); addline(ss);
  319.  
  320.     dflt(s1,"How many datasets do you want to draw lines or markers for","1");
  321.     nd = atoi(s1);
  322.     dflt(s1,"Do you want lines drawn for these datasets","no");
  323.     ss1[0] = 0;
  324.     if (tolower(*s1)=='y') strcpy(ss1,"lstyle 1");
  325.     dflt(s1,"Do you want markers drawn for these datasets","yes");
  326.     domark = false;
  327.     strcpy(ss2,"marker");
  328.     if (tolower(*s1)=='y') domark=true;
  329.  
  330.     for (i=0, m=0;i<nd;i++,m++) {
  331.         if (m>8) m=0;
  332.         if (!domark) {strcpy(ss2,""); m=9;}
  333.         sprintf(ss,"    d%d %s %s %s",i+1,ss1,ss2,mark_names[m]);
  334.         addline(ss);
  335.     }
  336. abort_idiot:;
  337.     addline("end graph");
  338. }
  339. int init_menucolor(void);
  340. int m_gstart,m_gend,m_dontdraw;
  341. menu()
  342. {
  343.     int nop=0,i,cc;
  344.     char dd[20],dd2[6],ds[3];
  345.     menutype *mi;
  346.  
  347.     init_menucolor();
  348.  
  349.     pmenu[0].menu = &graphmenu[0];
  350.     pmenu[1].menu = &xnamesmenu[0];
  351.     pmenu[2].menu = &ynamesmenu[0];
  352.     pmenu[3].menu = &x2namesmenu[0];
  353.     pmenu[4].menu = &y2namesmenu[0];
  354.     pmenu[5].menu = &x2axismenu[0];
  355.     pmenu[6].menu = &y2axismenu[0];
  356.     pmenu[7].menu = &fillmenu[0];
  357.     pmenu[8].menu = &barmenu[0];
  358.     pmenu[9].menu = &letmenu[0];
  359.     pmenu[10].menu = &xtramenu[0];
  360.  
  361.     initmenu();
  362.     token_space();
  363. /*    * Find begin...end graph commands */
  364.  
  365.     for (i=1;i<=ngtxt;i++) {
  366.         strcpy(srclin,(*gtxt)[i]);
  367.         token(srclin,(TOKENS) tk,&ntk,outbuff);
  368.         if (strcmp(tk[1],"BEGIN")==0  && strcmp(tk[2],"GRAPH")==0)
  369.             nop++;
  370.     }
  371.  
  372. /*    * Ask user which graph to edit  1...n */
  373.     {
  374.     pmenutype ask;
  375.     menutype *m;
  376.     char bb[20];
  377.         ask.ci = 0;
  378.         ask.menu = myallocn(1,sizeof(menutype)*10);
  379.         m = ask.menu;
  380.         for (i=0;i<=nop;i++,m++) {
  381.             sprintf(bb,"Graph %d",i+1);
  382.             setmenu(m,10,6+(i*2),MRETURN,0,0,"",bb,"gle loadgraph");
  383.             if (i==nop) m->val = sdup("Add/Create new Graph");
  384.             m->width = strlen(m->val);
  385.         }
  386.         setmenu(m,2,1,MNULL,0,0
  387.             ,"Select the graph in your file which you want to change (1=first graph)"
  388.             ,"","gle loadgraph");
  389.         m++;
  390.         setmenu(m,2,22,MNULL,0,0
  391.             ,"Use ^Z (Control+Z) to exit from each form"
  392.             ,"","gle loadgraph");
  393.         if (do_menu(&ask)) return;
  394.         i = ask.ci;
  395.         myfree(ask.menu);
  396.     }
  397.  
  398.     m_gstart = ngtxt+1;
  399.     m_gend = ngtxt;
  400.     if (i<nop) fillinmenu(i+1); else {
  401.         getsize();
  402.         idiot_questions();
  403.         return;
  404.     }
  405.     do_menu(&pmenu[0]);
  406.     extractmenu();
  407.     clrscr();
  408. }
  409. /*
  410.  
  411.     Getkey/command
  412.         arrowkeys normal
  413.         left and right arrow if editing
  414.         delete
  415.         insert normal character
  416.         enter, change to new menu
  417.         escape exit.
  418.         F1, help key
  419. */
  420. char mbuff[255];
  421.  
  422. extern int iserr;
  423. int hcx,cx,hcy;    /* HIlighted current x,y */
  424. do_menu(pmenutype *ppmenu)
  425. {
  426.     menutype *cm,*cmi,*si=NULL,*mi;
  427.     int citem,emode=false;
  428.     int c;
  429.     cm = ppmenu->menu;
  430.     citem = ppmenu->ci;
  431.     cmi = cm+citem;
  432.     refresh_menu(cm);
  433.     menu_hilight(cmi);
  434.     for (;;) {
  435.      c = text_inkey();
  436.      if (iserr) {fner_clear(); window(1,1,80,24);}
  437.      switch (c) {
  438.        case eescape: /* ESCAPE */
  439.        case equit: /* control c */
  440.         return true;
  441.        case eleft: /* left */
  442.         if (emode) {
  443.             if (cx>0) cx--;
  444.             gotoxy(hcx+cx,hcy);
  445.         } else {
  446.             for (si=NULL,mi=cm;mi->typ!=0;mi++) {
  447.                 if (mi->y==cmi->y && mi->x < cmi->x)
  448.                 if (si!=NULL) {
  449.                     if (mi->x > si->x)
  450.                         si = mi;
  451.                 } else si = mi;
  452.             }
  453.         }
  454.         break;
  455.        case eright: /* right */
  456.         if (emode) {
  457.             if (cx < strlen(cmi->val)) cx++;
  458.             gotoxy(hcx+cx,hcy);
  459.         } else {
  460.             for (si=NULL,mi=cm;mi->typ!=0;mi++) {
  461.                 if (mi->y==cmi->y && mi->x > cmi->x)
  462.                 if (si!=NULL) {
  463.                     if (mi->x < si->x)
  464.                         si = mi;
  465.                 } else si = mi;
  466.  
  467.             }
  468.         }
  469.         break;
  470.        case eup: /* arrow up */
  471.         emode = false;
  472.         for (si=NULL,mi=cm;mi->typ!=0;mi++) {
  473.             if (mi->typ<MNULL) {
  474.              if (si!=NULL) if (mi->y==si->y)
  475.                if (abs(mi->x - cmi->x) <  abs(si->x - cmi->x))
  476.                 si = mi;
  477.              if (mi->y < cmi->y) if (si!=NULL) {
  478.                if (mi->y > si->y) si = mi;
  479.              } else      si = mi;
  480.             }
  481.         }
  482.         break;
  483.        case edown: /* arrow down */
  484.         emode = false;
  485.         for (si=NULL,mi=cm;mi->typ!=0;mi++) {
  486.             if (mi->typ<MNULL) {
  487.              if (si!=NULL) if (mi->y==si->y)
  488.                if (abs(mi->x - cmi->x) <  abs(si->x - cmi->x))
  489.                 si = mi;
  490.              if (mi->y > cmi->y) if (si!=NULL) {
  491.                if (mi->y < si->y) si = mi;
  492.              } else  si = mi;
  493.             }
  494.         }
  495.         break;
  496.       case ehelp: /* f1 help */
  497.         do_help(cmi->help);
  498.         refresh_menu(cm);
  499.         menu_hilight(cmi);
  500.         break;
  501.       case ereturn: /* carriage return */
  502.         if (emode==true && cmi->typ==MFILE) {
  503.             emode = false;
  504.             break;
  505.         }
  506.         emode = false;
  507. doreturn:;
  508.         switch (cmi->typ) {
  509.           case MTEXT:
  510. /*            if (emode) emode = false; else emode = true; */
  511.             break;
  512.           case MTOGON:
  513.             cmi->typ = MTOGOFF;
  514.             menu_hilight(cmi);
  515.             break;
  516.           case MTOGOFF:
  517.             cmi->typ = MTOGON;
  518.             menu_hilight(cmi);
  519.             break;
  520.           case MRETURN:
  521.             goto exit_menu;
  522.           case MFILE:
  523.             if (mystrlen(cmi->val)==0) cmi->val = myalloc(20);
  524.             pick_file(cmi->val,"*.dat");
  525.             refresh_menu(cm);
  526.             menu_hilight(cmi);
  527.             break;
  528.           case MSUB: /* SUB MENU */
  529.             if (cmi->typ2>99) do_menu(&pmenu[cmi->typ2 - 100]);
  530.             refresh_menu(cm);
  531.             menu_hilight(cmi);
  532.         }
  533.  
  534.         for (si=NULL,mi=cm;mi->typ!=0;mi++) {
  535.             if (mi->y==cmi->y && mi->x > cmi->x)
  536.             if (si!=NULL) {
  537.                 if (mi->x < si->x)
  538.                     si = mi;
  539.             } else si = mi;
  540.         }
  541.  
  542.         break;
  543.       case edelete: /* delete */
  544.         emode = true;
  545.         if (cmi->val==NULL) break;
  546.         if (strlen(cmi->val)==0) break;
  547.         if (cx<1) break;
  548.         ncpy(mbuff,cmi->val,cx-1);
  549.         strcat(mbuff,cmi->val + cx);
  550.         setvstr(&cmi->val,mbuff);
  551.         cx--;
  552.         gotoxy(hcx+cx,hcy);
  553.         cputs(cmi->val + cx);
  554.         putch(DASHCHAR);
  555.         gotoxy(hcx+cx,hcy);
  556.         break;
  557.       case edrawit:
  558.         if (m_dontdraw)  break;
  559.         extractmenu();
  560.         window(1,1,79,24);
  561.         scr_grey();
  562.         clrscr();
  563.         gotoxy(1,1);
  564.         gle_redraw();
  565.         refresh_menu(cm);
  566.         menu_hilight(cmi);
  567.         break;
  568.       case eshowerror:
  569.         text_showerror();
  570.         refresh_menu(cm);
  571.         menu_hilight(cmi);
  572.         break;
  573.       case esave: /* save file */
  574.         extractmenu();
  575.         text_save();
  576.         break;
  577.       default: /* normal key */
  578.         if (c<26  && c!=9) {fner("Key has no affect"); break;}
  579.         if (c>200)  fner("Unimplemented command");
  580.         else {
  581. /*     if (cmi->typ!=MTEXT  && cmi->typ!=MFILE) goto doreturn; */
  582.             emode = true;
  583.             if (cmi->val==NULL) setvstr(&cmi->val,"");
  584.             ncpy(mbuff,cmi->val,cx);
  585.             mbuff[cx] = c; mbuff[cx+1] = 0;
  586.             strcat(mbuff,cmi->val + cx);
  587.             setvstr(&cmi->val,mbuff);
  588.             gotoxy(hcx+cx,hcy);
  589.             cputs(cmi->val + cx);
  590.             cx++;
  591.             gotoxy(hcx+cx,hcy);
  592.         }
  593.         break;
  594.      }
  595.      if (si!=NULL) {
  596.         menu_norm(cmi);
  597.         cmi = si;
  598.         menu_hilight(cmi);
  599.         si = NULL;
  600.      }
  601.     }
  602. exit_menu:;
  603.     /* save current point */
  604.     { int i;
  605.         for (i=0,mi=cm;mi->typ!=0;mi++,i++) {
  606.           if (mi==cmi) ppmenu->ci = i;
  607.         }
  608.     }
  609.     return false; /* normal exit */
  610. }
  611. setvstr(char **d, char *s)
  612. {
  613.     if ((*d) != 0) myfree(*d);
  614.     *d = sdup(s);
  615. }
  616. int mystrlen(char *s)
  617. {
  618.     if (s==NULL) return 0;
  619.     else return strlen(s);
  620. }
  621. menu_hilight(struct menu_struct *mm)
  622. {
  623.     int i,j;
  624.     struct menu_struct *m=mm;
  625.     scr_menuhi();
  626.     hcx = m->x + mystrlen(m->title);
  627.     hcy = m->y;
  628.     gotoxy(hcx,hcy);
  629.     if (m->typ==MTOGON || m->typ==MTOGOFF) {
  630.         if (m->val==NULL) m->val = myalloc(4);
  631.         if (m->typ==MTOGON) strcpy(m->val,"ON ");
  632.         if (m->typ==MTOGOFF) strcpy(m->val,"OFF");
  633.     }
  634.     if (m->val==NULL) setvstr(&m->val,"");
  635.     cputs(m->val);
  636.     j = m->width - mystrlen(m->val);
  637.     printdash(j);
  638.     cx = mystrlen(m->val);
  639.     gotoxy(hcx+cx,hcy);
  640. }
  641. printdash(int j)
  642. {
  643.     int i;
  644.     for (i=0;i<j;i++) mbuff[i] = DASHCHAR;
  645.     mbuff[j] = 0;
  646.     if (j>0) cputs(mbuff);
  647. }
  648. menu_norm(struct menu_struct *mm)
  649. {
  650.     int i,j;
  651.     struct menu_struct *m=mm;
  652.     gotoxy(m->x + mystrlen(m->title),m->y);
  653.     if (m->typ==MTOGON  || m->typ==MTOGOFF) {
  654.         if (m->val==NULL) m->val = myalloc(4);
  655.         if (m->typ==MTOGON) strcpy(m->val,"ON ");
  656.         if (m->typ==MTOGOFF) strcpy(m->val,"OFF");
  657.     }
  658.     if (m->val != NULL) {
  659.         scr_menuval();
  660.         if (m->width>0) cputs(m->val);
  661.         scr_menubg();
  662.     }
  663.     j = m->width - mystrlen(m->val);
  664.     printdash(j);
  665. }
  666. refresh_menu(struct menu_struct *mm)
  667. {
  668.     int i;
  669.     struct menu_struct *m=mm;
  670.     window(1,1,80,24);
  671.     scr_menubg();
  672.     clrscr();
  673.     for (;m->typ!=0;m++) {
  674.         if (m->title != NULL) if (strlen(m->title)>0) {
  675.             gotoxy(m->x,m->y);
  676.             cputs(m->title);
  677.         }
  678.         menu_norm(m);
  679.     }
  680. }
  681. extern char *tk[500];
  682. extern char inbuff[300];
  683. extern char tkbuff[500];
  684. extern char space_str[3];
  685. extern int ntk;
  686.  
  687. do_help(char *hstr)
  688. {
  689.     char ss[90];
  690.     strcpy(ss,"gle graph ");
  691.     strcat(ss,hstr);
  692.     do_help2(ss);
  693. }
  694. int fread_str(char *hbuff,int count, FILE *hidx);
  695. int fread_str(char *hbuff,int count, FILE *hidx)
  696. {
  697.     int i,slen;
  698.     hbuff[0] = 0;
  699.     i = fread(&slen,sizeof(slen),1,hidx);
  700.     if (i<=0) return i;
  701.     i = fread(hbuff,1,slen,hidx);
  702.     hbuff[slen] = 0;
  703.     return i;
  704. }
  705. do_help2(char *h)
  706. {
  707.     FILE *hfile,*hidx;
  708.     long hpnt,fipnt;
  709.     int i,yy,cp,match,capture;
  710.     char hbuff[91],mstr[90],mstr2[90],fk1[91];
  711.     char hstr[91],*s,*ss,hstr2[91];
  712.     char *hfilename="graph.hlp";
  713.     char subtopic[2000];
  714.     int atend;
  715.  
  716.     window(1,1,80,24);
  717.     strcpy(hstr,h);
  718.  
  719.     gotoxy(1,1);      scr_menuval();
  720.     clreol(); wprintf("   Working..."); scr_refresh();
  721.     hfile = fopen(gledir(hfilename),"rt");
  722.     if (hfile==NULL) {perror("Unable to open graph.hlp "); return;}
  723.     hidx = fopen(gledir("graph.idx"),"rb");
  724.     if (hidx==NULL) {perror("Unable to open graph.idx "); return;}
  725. help_again:;
  726.     rewind(hidx);
  727.     gotoxy(1,1);      scr_menuval();
  728.     clreol(); wprintf("   Working..."); scr_refresh();
  729.     subtopic[0] = 0;
  730.     strcpy(hstr2,hstr); token_data(hstr2,tk,&ntk,tkbuff);
  731.     for (i=1;i<=ntk;i++) strlwr(tk[i]);
  732.  
  733.     /* clear(); */
  734.     clrscr();
  735.  
  736.     if (ntk<2) tk[2] = "";
  737.     if (ntk<3) tk[3] = "";
  738.     if (*tk[2] == 'd' && strlen(tk[2])==2) tk[2] = "dn";
  739.     if (strcmp(tk[3],"yaxis")==0) tk[3] = "xaxis";
  740.     if (strcmp(tk[3],"y2axis")==0) tk[3] = "xaxis";
  741.     if (strcmp(tk[3],"x2axis")==0) tk[3] = "xaxis";
  742.     if (strcmp(tk[3],"ylabels")==0) tk[3] = "xlabels";
  743.     if (strcmp(tk[3],"y2labels")==0) {tk[3] = "xlabels"; tk[2] = "off";}
  744.     if (strcmp(tk[3],"x2labels")==0) {tk[3] = "xlabels"; tk[2] = "off";}
  745.     if (strcmp(tk[3],"ynames")==0) tk[3] = "xnames";
  746.     if (strcmp(tk[3],"y2names")==0) tk[3] = "xnames";
  747.     if (strcmp(tk[3],"x2names")==0) tk[3] = "xnames";
  748.     if (strcmp(tk[3],"ytitle")==0) tk[3] = "xtitle";
  749.     if (strcmp(tk[3],"y2title")==0) tk[3] = "xtitle";
  750.     if (strcmp(tk[3],"x2title")==0) tk[3] = "xtitle";
  751.     if (strcmp(tk[3],"title")==0) tk[3] = "xtitle";
  752.  
  753.     gotoxy(1,1); wprintf("GLE help ");
  754.     for (i=1;i<=ntk;i++) wprintf("{%s} ",tk[i]);
  755.     scr_menubg();
  756.  
  757.     /* Find match for each key word, display that section of file
  758.     and find rest of key words at that level */
  759.  
  760.     match = 1; /* trying to match a level one word */
  761.     capture = false;
  762.     for (;!feof(hidx);) {
  763.       if (fread_str(hbuff,90,hidx)!=0) {
  764.         fread(&fipnt,sizeof(fipnt),1,hidx);
  765.         sprintf(mstr,"%d",match);
  766.         sprintf(mstr2,"%d",match-1);
  767.         if (match>ntk) {
  768.           strcpy(fk1,hbuff); fk1[1] = 0;
  769.           i = atoi(fk1);
  770.           if (i>0 && i<match) { /* End of section */
  771.             goto got_help;
  772.           }
  773.           if (i>0 && i==match) { /* Sub topic */
  774.             capture = false;
  775.             strtok(hbuff," \t\n");
  776.             strcat(subtopic,strtok(NULL," \t\n"));
  777.             strcat(subtopic," ");
  778.           }
  779.           } else if (strncmp(hbuff,mstr,1)==0) { /* correct level */
  780.             strtok(hbuff," \t\n");
  781.             s = strtok(NULL," \t\n"); strcpy(fk1,s);
  782.             strlwr(fk1);
  783.             if (strncmp(fk1,tk[match],strlen(tk[match]))==0) {
  784.                 match++;
  785.                 if (match>ntk) {
  786.                     hpnt = fipnt;
  787.                      capture = true;
  788.                 }
  789.             }
  790.         }
  791.       }
  792.     }
  793.     scr_menuval();
  794.     gotoxy(1,9);
  795.     wprintf("Help text not found, press any key to continue ??? \n");
  796.     if (text_inkey()==eescape) goto quit_help;
  797.     strcpy(hstr,"gle");
  798.     goto help_again;
  799.  
  800. got_help:;
  801.     cp = 1;
  802. next_page:
  803.     atend = help_show(hfile,hpnt,subtopic,cp);
  804.  
  805.     scr_menuval();
  806.     gotoxy(1,23);
  807.     if (subtopic[0]==0) s = "Enter '-' to go up a level ";
  808.     else s = "Subtopic ";
  809.     strcpy(mstr,s);
  810.     if (!atend) strcat(mstr,"[next page] ");
  811.     else strcat(mstr,"[press return to exit help] ");
  812.     i = read_command(hbuff,mstr);
  813.     window(1,1,80,24);
  814.     if (i==epageup) {
  815.         cp -=18;
  816.         if (cp<0) cp = 0;
  817.         goto next_page;
  818.     }
  819.     if (i==epagedown) {
  820.         cp +=18;
  821.         if (cp<0) cp = 0;
  822.         goto next_page;
  823.     }
  824.     scr_menubg();
  825.     strupr(hbuff);
  826.     if (hbuff[0]=='-') {
  827.         strcpy(hstr2,hstr);
  828.         s = strtok(hstr2," \t");
  829.         for (;s!=NULL;) {ss = s; s = strtok(NULL," \t");}
  830.         *strstr(hstr,ss) = 0;
  831.         goto help_again;
  832.     }
  833.     if (strlen(hbuff)!=0) {
  834.         strcat(hstr," ");
  835.         strcat(hstr,hbuff);
  836.         goto help_again;
  837.     }
  838.     if (!atend) {cp+=18; goto next_page;}
  839.  
  840. quit_help:;
  841.     fclose(hfile);
  842.     fclose(hidx);
  843. }
  844. int help_show(FILE *hfile, long hpnt, char *st, int cp)
  845. {
  846.     int i=1,sl=3;
  847.     int lvl= -1;
  848.     char hbuff[100],*s;
  849.     char subtopic[2000];
  850.  
  851.     strcpy(subtopic,st);
  852.     fseek(hfile,hpnt,SEEK_SET);
  853.     window(1,1,80,24);
  854.     clrscr();
  855.     scr_menuval();
  856.     gotoxy(1,1); wprintf("GLE help ");
  857.     for (i=1;i<=ntk;i++) wprintf("{%s} ",tk[i]);
  858.     scr_menubg();
  859.     for (;!feof(hfile) && sl<18;) {
  860.       if (fgets(hbuff,90,hfile)!=NULL) {
  861.         lvl = hbuff[0]-'0';
  862.         if (lvl>0 && lvl<9) goto end_section;
  863.         if (i>cp) {
  864.             gotoxy(1,sl++); cputs(tabtospace(hbuff));
  865.         }
  866.         i++;
  867.       }
  868.     }
  869. end_section:
  870.     if (strlen(subtopic)==0) goto skip_sub;
  871.  
  872.     sl++;
  873.     gotoxy(1,sl++); cputs("Subtopics:");
  874.  
  875.     s = strtok(subtopic," \t\n");
  876.     for (i=1;s!=NULL;i++) {
  877.       if (i==1) strcpy(hbuff,"\t");
  878.       if (strcmp(s,"(end)")!=0) {
  879.         strcat(hbuff,s); strcat(hbuff,"\t");
  880.         if (strlen(s)>7) i++;
  881.         if (i>6) {
  882.             gotoxy(1,sl++); cputs(tabtospace(hbuff));
  883.             hbuff[0] = 0;
  884.             i = 0;
  885.             if (sl>21) return false;
  886.         }
  887.       }
  888.       s = strtok(NULL," \t\n");
  889.     }
  890.     gotoxy(1,sl++); cputs(tabtospace(hbuff));
  891. skip_sub:;
  892.     if (!(lvl>0 && lvl<9) ) return false;
  893.     return true; /* not finished */
  894. }
  895. add_unrecognized(char *s)
  896. {
  897.     if (nunrec>6) return;
  898.     xtramenu[nunrec++].val = sdup(s);
  899. }
  900. int vunquote(char **s);
  901. vunquote(char **ss)
  902. {
  903.     char *s = *ss;
  904.     if (*s=='\"') {
  905.         s[strlen(s)-1] = 0;
  906.         *ss = sdup(s+1);
  907.         myfree(s);
  908.     }
  909. }
  910.  
  911. int initmenudone;
  912. menutype *m_pnt[20];
  913. menutype *m_end[20];
  914. char *m_val[20];
  915. char m_tog[50];
  916. initmenu()
  917. {
  918.     menutype *mi;
  919.     char *s,kw1[80],kw2[80];
  920.     int i,j,nt=0,k,z,ct,used;
  921.     static int nv;
  922.  
  923.     if (!initmenudone) {
  924.       minit_extras();
  925.       initmenudone = true;
  926.       for (z=0;z<=10;z++) {
  927.         for (mi=pmenu[z].menu; mi->typ!=0; mi++) {
  928.         if (mi->typ==MTOGON || mi->typ==MTOGOFF) {
  929.             m_tog[nt++] = mi->typ;
  930.         }
  931.         if (mi->val!=NULL) {
  932.             m_val[nv] = sdup(mi->val);
  933.             mi->val = sdup(mi->val);
  934.             m_pnt[nv++] = mi;
  935.         }
  936.         }
  937.       }
  938.     } else {
  939.       for (z=0;z<=10;z++) {
  940.         for (mi=pmenu[z].menu; mi->typ!=0; mi++) {
  941.         if (mi->typ==MTOGON || mi->typ==MTOGOFF) {
  942.             mi->typ = m_tog[nt++];
  943.         } else {
  944.             if (mi->val!=0) {
  945.                 myfree(mi->val);
  946.             }
  947.             mi->val = 0;
  948.         }
  949.         }
  950.       }
  951.       for (z=0;z<nv;z++) {
  952.         mi = m_pnt[z];
  953.         mi->val = sdup(m_val[z]);
  954.       }
  955.     }
  956. }
  957.  
  958. minit_extras()
  959. {
  960.     char dd[29],dd2[9],ds[9];
  961.     menutype *mi;
  962.     int i;
  963.  
  964.     i = 0;
  965.     for (mi=graphmenu;mi->typ!=0;mi++) i++;
  966.     for (i=0;i<9;i++) {
  967.       setmenu(mi,2,13+i,MFILE,SROL,20,"",0,"data");mi++;
  968.     }
  969.     for (i=0;i<9;i++) {
  970.      sprintf(ds,"d%d ",i);
  971.      if (i==0) strcpy(ds,"dn ");
  972.      sprintf(dd,"%smarker",ds); setmenu(mi,23,13+i,MTEXT,0,10,ds,0,dd); mi++;
  973.      sprintf(dd,"%slstyle",ds); setmenu(mi,37,13+i,MTEXT,0,4,"",0,dd); mi++;
  974.      sprintf(dd,"%scolor",ds);  setmenu(mi,42,13+i,MTEXT,0,7,"",0,dd); mi++;
  975.      sprintf(dd,"%slwidth",ds); setmenu(mi,50,13+i,MTEXT,0,4,"",0,dd); mi++;
  976.      sprintf(dd,"%ssmooth",ds); setmenu(mi,56,13+i,MTOGOFF,SS,3,"",0,dd); mi++;
  977.      sprintf(dd,"%skey",ds);    setmenu(mi,60,13+i,MTEXT,SSTR,15,"",0,dd); mi++;
  978.      sprintf(dd,"%serr",ds);    setmenu(mi,76,13+i,MTEXT,0,3,"",0,dd); mi++;
  979.      sprintf(dd,"%serrup",ds);  setmenu(mi,78,13+i,MTEXT,0,0,"",0,dd); mi++;
  980.      sprintf(dd,"%serrdown",ds); setmenu(mi,78,13+i,MTEXT,0,0,"",0,dd); mi++;
  981.      sprintf(dd,"%smsize",ds); setmenu(mi,78,13+i,MTEXT,0,0,"",0,dd); mi++;
  982.      sprintf(dd,"%smscale",ds); setmenu(mi,78,13+i,MTEXT,0,0,"",0,dd); mi++;
  983.      sprintf(dd,"%serrwidth",ds); setmenu(mi,78,13+i,MTEXT,0,0,"",0,dd); mi++;
  984.     }
  985. }
  986. char msend[200];
  987. #define mss msend+strlen(msend)
  988. char cs[80]="xyz";
  989. int gstartend;
  990. extractmenu()
  991. {
  992.     menutype *mi;
  993.     char *s,kw1[80],kw2[80];
  994.     int i,j,k,z,ct,used;
  995.  
  996.     if ((m_gstart==0) && (m_gend==0)) return;
  997.     gstartend = m_gstart;
  998.     for (i=gstartend;i<=m_gend;i++) vdelete(gstartend);
  999.  
  1000.     if (graphmenu[2].val!=NULL) {
  1001.       if (strcmp(graphmenu[2].val,"")!=0) {
  1002.         sprintf(msend,"amove %s %s ",graphmenu[2].val,graphmenu[3].val);
  1003.         m_sendline();
  1004.       }
  1005.     }
  1006.     sprintf(msend,"begin graph ");
  1007.     m_sendline();
  1008.     for (z=0;z<=10;z++) {
  1009.       for (mi=pmenu[z].menu; mi->typ!=0; mi++) {
  1010.         if (mi->typ < MSUB  && mi->val!=NULL) {
  1011.          if (strcmp(mi->val,"")!=0) {
  1012.           ncpy(kw1,mi->help,strcspn(mi->help," "));
  1013.           strcpy(kw2,"");
  1014.           if (strlen(kw1)<strlen(mi->help))
  1015.         strcpy(kw2,mi->help + strlen(kw1) + 1);
  1016.           switch (mi->typ2) {
  1017.         case SSIZE:
  1018.             m_sendline();
  1019.             sprintf(msend,"\tsize %s %s ",mi->val,(mi+1)->val);
  1020.             mi++;
  1021.             m_sendline();
  1022.             break;
  1023.         case SNOBOX:
  1024.             if (mi->typ==MTOGOFF) {
  1025.                 m_sendline();
  1026.                 sprintf(msend,"\tnobox ");
  1027.                 m_sendline();
  1028.             }
  1029.             break;
  1030.         case SNEXTS:
  1031.             m_sendline();
  1032.             strcpy(cs,kw1);
  1033.             sprintf(mss,"\t%s \"%s\" ",kw1,mi->val);
  1034.             break;
  1035.         case SROL:
  1036.             m_sendline();
  1037.             if (strcmp(kw1,"xtra")==0) {
  1038.                 sprintf(mss,"\t%s",mi->val);
  1039.             } else {
  1040.                 sprintf(mss,"\t%s %s",kw1,mi->val);
  1041.             }
  1042.             break;
  1043.         case SSTR:
  1044.             m_ifsend(kw1);
  1045.             sprintf(mss,"%s \"%s\" ",kw2,mi->val);
  1046.             break;
  1047.         case SNORM:
  1048.             /* printf("ifsend cs={%s} k1={%s} {%s} \n",cs,kw1,kw2);*/
  1049.             m_ifsend(kw1);
  1050.             sprintf(mss,"%s %s ",kw2,mi->val);
  1051.             break;
  1052.         case STOG:
  1053.         case SS:
  1054.             if (mi->typ==MTOGON) {
  1055.                 m_ifsend(kw1);
  1056.                 sprintf(mss,"%s ",kw2);
  1057.             }
  1058.             break;
  1059.         case SSOFF:
  1060.             if (mi->typ==MTOGOFF) {
  1061.                 m_ifsend(kw1);
  1062.                 sprintf(mss,"%s ",kw2);
  1063.             }
  1064.             break;
  1065.         case SAMOVE:
  1066.             break;
  1067.           }
  1068.         }
  1069.        }
  1070.       }
  1071.     }
  1072.     m_sendline();
  1073.     sprintf(msend,"end graph");
  1074.     m_sendline();
  1075.     m_gend = gstartend-1;
  1076. }
  1077. /* char msend[200]; */
  1078. m_sendline()
  1079. {
  1080.     if (strlen(msend)>0) vinsert(gstartend++,msend);
  1081.     msend[0] = 0;
  1082.     strcpy(cs,"xyz");
  1083. }
  1084. m_ifsend(char *s)
  1085. {
  1086.     if (strcmp(s,cs)!=0) {
  1087.       m_sendline();
  1088.       sprintf(msend,"\t%s ",s);
  1089.       strcpy(cs,s);
  1090.     }
  1091. }
  1092. int g_get_usersize(double *x, double *y);
  1093. getsize()
  1094. {
  1095.     static char s1[29], s2[29];
  1096.     double x,y;
  1097. /*     g_get_usersize(&x,&y);*/
  1098.     x = 24; y = 18;
  1099.     if (x==0) return;
  1100.     sprintf(s1,"%g",x); sprintf(s2,"%g",y);
  1101.     graphmenu[0].val = sdup(s1);
  1102.     graphmenu[1].val = sdup(s2);
  1103. }
  1104. fillinmenu(int nbegin)
  1105. {
  1106.     menutype *mi;
  1107.     char *s,kw[80],mkw[80];
  1108.     int aa,i,j,k,z,nmatch=0,ct,nop=0,used,gotit;
  1109.     menutype *match[200];
  1110.     m_gstart = 0;
  1111.     nunrec = 0;
  1112. /* for each line, compare first word on line to all first words, */
  1113.     for (i=1;i<=ngtxt;i++) {
  1114.         strcpy(srclin,(*gtxt)[i]);
  1115.         token(srclin,(TOKENS) tk,&ntk,outbuff);
  1116.         if (strcmp(tk[1],"AMOVE")==0) {
  1117.             m_gstart = i;
  1118.             graphmenu[2].val = sdup(tk[2]);
  1119.             graphmenu[3].val = sdup(tk[3]);
  1120.         }
  1121.         if (strcmp(tk[1],"BEGIN")==0  && strcmp(tk[2],"GRAPH")==0) {
  1122.             nop++;
  1123.             if (nop==nbegin) break;
  1124.         }
  1125.     }
  1126.     if ((m_gstart+1 !=i)  || (m_gstart==0))   m_gstart = i;
  1127.  
  1128.     pmenu[0].menu = graphmenu;
  1129.  
  1130.     for (i++;i<=ngtxt;i++) {
  1131.         strcpy(srclin,(*gtxt)[i]);
  1132.         token(srclin,(TOKENS) tk,&ntk,outbuff);
  1133.         gotit = false;
  1134.         ct = 2;
  1135.         strcpy(kw,tk[1]);
  1136.         strlwr(kw);
  1137.         used = false;
  1138.         nmatch = 0;
  1139.         if (strcmp(tk[1],"END")==0) break;
  1140.         for (z=0;z<10;z++) {
  1141.         for (mi=pmenu[z].menu; mi->typ!=0; mi++) {
  1142.           j = strlen(tk[1]);
  1143.           if (ntk<1) if (strchr(srclin,'!')!=NULL) {
  1144.               if (*srclin == '\t') aa=1; else aa=0;
  1145.               add_unrecognized(srclin+aa);
  1146.               ct = ntk + 1;
  1147.               gotit = true;
  1148.               goto next_xinline;
  1149.           }
  1150.           ct = 2;
  1151.           if (j>1)  if (strncmp(kw,mi->help,j)==0) {
  1152.             switch (mi->typ2) {
  1153.               case STOG:
  1154.               case SSTR:
  1155.               case SSOFF:
  1156.               case SS:
  1157.               case SNORM: /* Just remember this one for later */
  1158.             match[nmatch++] = mi;
  1159.             used=true;
  1160.             break;
  1161.               case SNOBOX:
  1162.             mi->typ = MTOGOFF;
  1163.             used = true;
  1164.             break;
  1165.               case SSIZE:
  1166.             mi->val = sdup(tk[2]);
  1167.             (++mi)->val = sdup(tk[3]);
  1168.             used = true; ct = ntk+1;
  1169.             goto next_xinline;
  1170.             break;
  1171.               case SROL: /* e.g. let, bar, fill,xnames,xplaces */
  1172.             if (mystrlen(mi->val)!=0) break;
  1173.             k = strspn(srclin," \t");
  1174.             k = k + strcspn(srclin+k," \t");
  1175.             k = k + strspn(srclin+k," \t");
  1176.             mi->val = sdup(srclin+k);
  1177.             used=true;
  1178.             ct = ntk+1;
  1179.             goto next_xinline;
  1180.               case SNEXTS: /* E.G. TITLE "XXX" ... or bar d1,d2 ...*/
  1181.             mi->val = sdup(tk[2]);
  1182.             vunquote(&mi->val);
  1183.             ct = 3; used=true;
  1184.             break;
  1185.               case SSNULL:
  1186.             break;
  1187.             }
  1188.           }
  1189.         }
  1190.         }
  1191. next_xinline:;
  1192.         if (used==false && !gotit) {
  1193.           wprintf("Warning, unrecognized graph command {%s}\n"
  1194.                     ,tk[1]);
  1195.           gotit = true;
  1196.           if (*srclin == '\t') aa=1; else aa=0;
  1197.           add_unrecognized(srclin+aa);
  1198.         }
  1199.         used = true;
  1200.         for (j=ct;j<=ntk;j++) {
  1201.           used = false;
  1202.           strcpy(kw,tk[j]);
  1203.           strlwr(kw);
  1204.           for (k=0;k<nmatch;k++) {
  1205.             mi = match[k];
  1206. /* gprint("match {%s} {%s}  {%s} \n",kw,mi->help,srclin); */
  1207.             switch (mi->typ2) {
  1208.               case STOG:
  1209.             if (strcmp(kw,"on")==0) {mi->typ = MTOGON; used=true;}
  1210.             if (strcmp(kw,"off")==0) {mi->typ = MTOGOFF; used=true;}
  1211.             break;
  1212.               default:
  1213.             strcpy(mkw,mi->help);
  1214.             s = strtok(mkw," "); s = strtok(0," ");
  1215.             if (s!=NULL) if (strcmp(s,"lstyle")==0)
  1216.               if (strcmp(kw,"line")==0) {mi->val = sdup("1"); used=true;}
  1217.             if (s!=NULL) if (strcmp(s,kw)==0) {
  1218.                 if (mi->typ2 == SS || mi->typ2 == SSOFF) {
  1219.                     mi->typ = MTOGON;
  1220.                     if (mi->typ2==SSOFF) mi->typ = MTOGOFF;
  1221.                     used = true;
  1222.                 } else {
  1223.                  used = true;
  1224.                  mi->val = sdup(tk[j+1]);
  1225.                  j++;
  1226.                  vunquote(&mi->val);
  1227.                 }
  1228.             }
  1229.             }
  1230.           }
  1231.           /*      if (used==false && !gotit) {
  1232.               if (*srclin == '\t') aa=1; else aa=0;
  1233.               add_unrecognized(srclin+aa);
  1234.               wprintf("\n lost command {%s} \n",tk[j]);
  1235.               gotit = true;
  1236.               wprintf("Press a key\n"); text_inkey();
  1237.           }*/
  1238.         }
  1239.     }
  1240.     m_gend = i;
  1241. /*    * Rad in graph commands, for each initial key word
  1242.         compare to all menu keywords and if match is RESTOFLINE
  1243.         type then (set item to occupied )
  1244.         and copy rest of line into value part of menu.
  1245.         else add to list of matches:
  1246.         for each word in rest of line compare to each
  1247.         matched item, and if match then put in menu value.
  1248.         (if first keyword not found then add too not
  1249.         understood list to be written out at end)
  1250.         (if second word not matched then print warning message)
  1251. */
  1252. }
  1253. setmenu(menutype *m,int x, int y, int typ, int typ2, int width, char *title
  1254. , char *val, char *help)
  1255. {
  1256.     m->x = x; m->y = y; m->typ = typ; m->typ2 = typ2; m->width = width;
  1257.     m->title = sdup(title);
  1258.     if (val!=0) m->val = sdup(val);
  1259.     m->help = sdup(help);
  1260. }
  1261. init_menucolor()
  1262. {
  1263.         h_bcolor = WHITE; h_fcolor = BLACK;
  1264. }
  1265. static int saveplace;
  1266. int pick_file(char *result, char *wld)
  1267. {
  1268.     pmenutype ask;
  1269.     char wild[80];
  1270.     char buff2[80];
  1271.     char *f[80];
  1272.     char *swap;
  1273.     menutype *m,*mi,*mwild;
  1274.     struct ffblk ffblk;
  1275.     int done,i,x,y,nf,rval,adddir=false;
  1276.  
  1277.     strcpy(wild,wld);
  1278.     ask.ci = saveplace;
  1279. pick_again:;
  1280.     x=0; y=0; nf=0;
  1281.     init_menucolor();
  1282.     done = findfirst(wild,&ffblk,0);
  1283.     for (nf=0;nf<70 && !done;nf++) {
  1284.         f[nf] = sdup(ffblk.ff_name);
  1285.         done = findnext(&ffblk);
  1286.     }
  1287. sortagain:;
  1288.     swap = NULL;
  1289.     for (i=0;i<(nf-1);i++) {
  1290.         if (strcmp(f[i],f[i+1])>0) {
  1291.             swap = f[i]; f[i] = f[i+1]; f[i+1] = swap;
  1292.         }
  1293.     }
  1294.     if (swap != NULL) goto sortagain;
  1295.  
  1296.     m = myallocn(3+nf,sizeof(*m));
  1297.     ask.menu = m;
  1298.     ask.ci = saveplace;
  1299.     if (saveplace>nf) ask.ci = 0;
  1300.     if (nf==0) ask.ci = 1;
  1301.     if (m==0) wprintf("memory allocation error");
  1302.     for (mi=m,i=0;i<nf;i++,mi++) {
  1303.         setmenu(mi,x*20+1,y+5,MRETURN,0,18,"",f[i],"");
  1304.         x++;
  1305.         if (x==4) {x=0; y++; }
  1306.     }
  1307.     setmenu(mi,5,1,MNULL,0,0,"Use arrow keys to select file then press return","","");
  1308.     mi++;
  1309.     setmenu(mi,5,3,MRETURN,0,30,"Disk/Dir Specification ",wild,"");
  1310.     mwild = mi;
  1311.     mi++; mi->typ = 0;
  1312.     m_dontdraw = true;
  1313.     rval = do_menu(&ask);
  1314.     saveplace = ask.ci;
  1315.     m_dontdraw = false;
  1316.     strcpy(result,((ask.menu)[ask.ci]).val);
  1317.     for (i=0;i<nf;i++) myfree(f[i]);
  1318.     myfree(m);
  1319.  
  1320.     if (strcmp(wild,mwild->val)!=0) {
  1321.         strcpy(wild,mwild->val);
  1322.         if (strstr(wild,"*")==NULL) {
  1323.             if (wild[strlen(wild)-1] == '\\')
  1324.                 strcat(wild,"*.gle");
  1325.             else
  1326.                 strcat(wild,"\\*.gle");
  1327.         }
  1328.         adddir = true;
  1329.         goto pick_again;
  1330.     }
  1331.  
  1332.     if (adddir) {
  1333.         *(strfile(wild)) = 0;
  1334. #ifdef __TURBOC__
  1335.         if (strstr(wild,":")!=NULL || strlen(wild)==1) {
  1336.             setdisk(toupper(*wild)-'A');
  1337.             if (strlen(wild)>1)
  1338.                 {strcpy(buff2,wild+2); strcpy(wild,buff2);}
  1339.         }
  1340. #endif
  1341.         if (strlen(wild)!=1) if (chdir(wild)!=0) {perror("Cannot change dir"); delay(3000);}
  1342.     }
  1343.  
  1344. /*    if (adddir) {
  1345.         *(strfile(wild)+1) = 0;
  1346.         strcpy(result,wild);
  1347.         strcat(result,((ask.menu)[ask.ci]).val);
  1348.     }
  1349. */
  1350.     return rval;
  1351. }
  1352. char *strfile(char *s)
  1353. {
  1354.     char *e;
  1355.     e = s;
  1356.     for (;*s!=0;s++) {
  1357.         if (*s==']'  ||  *s=='\\' || *s=='/' || *s==':') e = s;
  1358.     }
  1359.     return e;
  1360. }
  1361.  
  1362.