home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / CONTRIB / MBASE / MBASE50.TAR / mbase / src / vr.c < prev   
Encoding:
C/C++ Source or Header  |  1993-05-21  |  13.5 KB  |  669 lines

  1. /*
  2.  * METALBASE 5.0
  3.  *
  4.  * Released October 1st, 1992 by Huan-Ti [ richid@owlnet.rice.edu ]
  5.  *                                       [ t-richj@microsoft.com ]
  6.  */
  7.  
  8. #include "mbase.h"
  9.  
  10. #define movech(c,y,x)  move(y,x);refresh();c=getarr();
  11. #define doing(x,o)     (arr == x && opt == o && go == 1)
  12.  
  13. #ifdef LONGARGS
  14. void    main         (int, char **);
  15. void    paint_scrn (int, int);
  16. int         get_rel     (char *);
  17. void    get_index     (void);
  18. void    get_rel_name (void);
  19. void    add_rec        (int);
  20. void    del_rec        (void);
  21. void    do_error    (char *);
  22. void    sel_rec     (int);
  23. void    fill_page  (void);
  24. int         verify      (char *);
  25. void    zero_rec    (void);
  26. void    do_line     (int, int);
  27. #else
  28. void    main();
  29. void    paint_scrn();
  30. int         get_rel();
  31. void    get_index();
  32. void    get_rel_name();
  33. void    do_error();
  34. void    add_rec();
  35. void    del_rec();
  36. void    sel_rec();
  37. void    fill_page();
  38. int         verify();
  39. void    zero_rec();
  40. void      do_line();
  41. #endif
  42.  
  43. static int num_[]      = { 13 };
  44. static int opt_[][20] = {{ 0, 6, 11, 16, 21, 26, 30, 34, 41, 45, 49, 53, 57 }};
  45. static char *line_[]  =
  46.  { "First Last Next Prev Gteq Equ Idx Screen Add Upd Del Rel Quit" };
  47.  
  48. #ifdef MSDOS
  49. #define Standout()
  50. #define Standend()
  51. #else
  52. #define Standout() standout()
  53. #define Standend() standend()
  54. #endif
  55.  
  56. relation *rel = (relation *)0;
  57. char    name[20];
  58. int        pg, pgmax, iserr=0, inw=0, pglst, idx;
  59. dataptr    buf;
  60. #define ROWS    (LINES - 7)
  61. #define FIRSTCOL    18
  62.  
  63. void clean(int i)
  64. {
  65.  
  66.     clear();
  67.     refresh();
  68.     resetty();
  69.     endwin();
  70.     mb_exit(i);
  71. }
  72.  
  73. void
  74. main  (argc, argv)
  75. int     argc;
  76. char **argv;
  77. {
  78. int  c, opt = 0, arr = 0, go, esc=0;
  79.  
  80.     init_curses();
  81.  
  82.     if (argc > 2) { 
  83.             fprintf (stderr, "vr: format: vr [relation]%s", SNGCR);
  84.             clean(1);
  85.      }
  86.  
  87.     if (argc == 2)
  88.             if (! get_rel (argv[1])) {
  89.                   fprintf (stderr,"vr: invalid argument (%s)%s",mb_error,SNGCR);
  90.                 clean(1);
  91.              }
  92.  
  93.     inw = 1; 
  94.     savetty();
  95.     raw(); 
  96.     noecho(); 
  97.     nl();
  98.     paint_scrn (0, 1);
  99.  
  100.     if (rel)  fill_page();
  101.  
  102.     for (;;) {
  103.         movech(c, 0,opt_[arr][opt]);  
  104.         go = 0;  
  105.         if (iserr)  
  106.             do_error("");
  107. #ifdef VI_EMU
  108.         if (c != 27)  
  109.             esc = 0;
  110.         else
  111.             if (esc == 1)  
  112.                 break;
  113.             else              
  114.                 esc = 1;
  115. #endif
  116.  
  117.         switch (c) { 
  118.         case ' ': case AR_RIGHT: 
  119.             opt++;    
  120.             break;
  121.           case '\b': case 127: case AR_LEFT:  
  122.               opt--;    
  123.               break;
  124.           case '?': case '/':  
  125.               paint_scrn(-1,0);        
  126.               break;
  127.           case CTRL_L: 
  128.               clearok(win,TRUE); 
  129.               refresh();      
  130.               break;
  131.          }
  132.         if (arr == 0)
  133.             switch (c=tolower(c)) {
  134.             case '\n': case '\r': go = 1;  break;
  135.             case  'f':  opt = 0;  go = 1;  break;
  136.             case  'l':  opt = 1;  go = 1;  break;
  137.             case  'n':  opt = 2;  go = 1;  break;
  138.             case  'p':  opt = 3;  go = 1;  break;
  139.             case  'g':  opt = 4;  go = 1;  break;
  140.             case  'e':  opt = 5;  go = 1;  break;
  141.             case  'i':  opt = 6;  go = 1;  break;
  142.             case  's':  opt = 7;  go = 1;  break;
  143.             case  'a':  opt = 8;  go = 1;  break;
  144.             case  'u':  opt = 9;  go = 1;  break;
  145.             case  'd':  opt =10;  go = 1;  break;
  146.             case  'r':  opt =11;  go = 1;  break;
  147.             case  'q':  opt =-1;  go = 1;  break;
  148.              }
  149.  
  150.             if (opt == -1) 
  151.                 opt = num_[arr]-1;
  152.             if (opt == num_[arr])  opt = 0;
  153.  
  154.             if (arr==0 && go==1 && opt < 11 && rel==RNULL && opt >= 0)
  155.                 do_error("specify new relation first"),go=0;
  156.             if (arr==0 && go==1 && (opt==9||opt==10) && rel->pos == 0L)
  157.                 do_error("select a record first"),go=0;
  158.  
  159.             if (doing (0, -1))  break;
  160.             if (doing (0, 12))  break;
  161.             if (doing (0,  0))  sel_rec (FIRST);
  162.             if (doing (0,  1))  sel_rec (LAST);
  163.             if (doing (0,  2))  sel_rec (NEXT);
  164.             if (doing (0,  3))  sel_rec (PREVIOUS);
  165.             if (doing (0,  4))  sel_rec (GTEQ);
  166.             if (doing (0,  5))  sel_rec (EQUAL);
  167.             if (doing (0,  6))  get_index();
  168.             if (doing (0,  7)) {
  169.                 pg++;
  170.                 if (pg > pgmax) pg = 1;
  171.                 fill_page();
  172.                 paint_scrn(arr,0);
  173.             }
  174.             if (doing (0,  8))  add_rec(1);
  175.             if (doing (0,  9))  add_rec(0);
  176.             if (doing (0, 10))  del_rec();
  177.             if (doing (0, 11))  get_rel_name();
  178.     }
  179.  
  180.     if (buf) 
  181.         free(buf);
  182.     
  183.     clean(0);
  184. }
  185.  
  186. void
  187. paint_scrn (opt, init)
  188. int            opt, init;
  189. {
  190. char temp[128];
  191.  
  192.     if (init) { 
  193.         clear();
  194.         attron(A_BOLD);
  195.         mvaddstr (0, COLS - 14, "MetalBase 5.0");
  196.         attroff(A_BOLD);
  197.         move(1,  0);
  198.         hline(ACS_HLINE, COLS);
  199.         addch(ACS_HLINE);
  200.     }
  201.     if (opt != -1) {
  202.         mvaddstr (0,  0, line_[opt]);
  203.         refresh();
  204.     }
  205.     if (opt == -1 || init) {
  206.         if (rel == RNULL)
  207.             strcpy  (temp, "no relation given");
  208.         else
  209.             sprintf (temp, "%s.rel -- %ld records, %d indices -- Page %d of %d",
  210.                              name, mb_num(rel), rel->num_i, pg,pgmax);
  211.         move(2, 0);  
  212.         clrtoeol();
  213.         mvaddstr(2, (COLS-strlen(temp))/2, temp);
  214.     }
  215.     refresh();
  216. }
  217.  
  218. void
  219. get_index ()
  220. {
  221. int  i;
  222. char ptr[128];
  223.  
  224.     move (4, 0);  
  225.     clrtobot();
  226.     for (i = 0; i < min (rel->num_i, 16); i++) {
  227.         sprintf (ptr, "Index #%2d - %s", i+1, rel->iname[i]);
  228.         mvaddstr (6+i, 10, ptr);
  229.     }
  230.     sprintf (ptr, "%s", rel->iname[idx]);  
  231.     do_error ("Select index");
  232.  
  233.     mvaddstr (4, 10, "Index Name or Number : ");  
  234.     refresh();
  235.     if ((input (ptr, 0, 20) < 0) || ptr[0] == 0) {
  236.           fill_page();  
  237.          do_error("Index selection aborted"); 
  238.          return; 
  239.      }
  240.  
  241.     if ((i = atoi (ptr)-1) < 0)  i = idxnum (rel, ptr);
  242.  
  243.     if (i < 0 || i > 16 || i >= rel->num_i) {
  244.           fill_page ();
  245.         do_error  ("Invalid index -- selection aborted");
  246.         return;
  247.     }
  248.  
  249.     idx = i;  
  250.     sprintf (ptr, "New index: #%d (%s)", idx+1, rel->iname[idx]);
  251.     fill_page();  
  252.     do_error(ptr);
  253. }
  254.  
  255. void
  256. get_rel_name ()
  257. {
  258. char    nm[128], *c;
  259. mb_err     d;
  260.  
  261.     move(4, 0);  
  262.     clrtobot();
  263.     addstr("Relation Name        : ");  
  264.     refresh();  
  265.     nm[0] = 0;
  266.     input(nm, 0, 60);
  267.     if ((! *nm) || (*nm && !get_rel(nm))) {
  268.           c = mb_error;
  269.          d = mb_errno;
  270.         fill_page();  
  271.         if (d)  do_error(c);
  272.         paint_scrn(-1, 0);
  273.      }
  274. }
  275.  
  276. int
  277. get_rel (file)
  278. char     *file;
  279. {
  280. char    pw[80], t[80];
  281. int      i;
  282.  
  283.     i = strlen(file);
  284.     if (! strcmp (&file[i-4], ".rel"))  file[i-4] = 0;
  285.     for (i = strlen(file); i >= 0; i--)
  286.         if (file[i] == '/' || file[i] == ':')  break;
  287.     strcpy (t, &file[i+1]);
  288.  
  289.     if (mb_tst (file))  return 0;
  290.  
  291.     if (rel)  mb_rmv(rel),rel=RNULL;
  292.     if (buf)  free(buf),  buf=NULL;
  293.     pg = pgmax = pglst = 0; strcpy (name, t);
  294.  
  295. #ifdef NOENCRYPT
  296.     pw[0] = 0;
  297. #else
  298.     if (! inw) {
  299.           fputs("Encryption password: ", stdout); 
  300.           fflush(stdout); 
  301.           fgets(stdin, pw, 80);
  302.      } else {
  303.          move(5, 0);
  304.         addstr("Encryption password: ");  
  305.         refresh();
  306.         pw[0] = 0;
  307.         input(pw, 0, 60);
  308.         move(4, 0);  
  309.         clrtobot();  
  310.         refresh();
  311.      }
  312. #endif
  313.     if ((rel = mb_inc (file, strtokey (pw))) == RNULL)  return 0;
  314.     buf = (dataptr)malloc (rel->rec_len + 1);
  315.     pgmax = (rel->num_f / ROWS) + 1;  
  316.     idx = 0;
  317.     pglst = rel->num_f % ROWS;  
  318.     pg = 1;  
  319.     if (inw)  
  320.         fill_page();
  321.     zero_rec();
  322.     return 1;
  323. }
  324.  
  325. void
  326. do_error (line)
  327. char      *line;
  328. {
  329.     move (LINES-1, 0);    
  330.     clrtoeol();  
  331.     iserr = 0;
  332.     if (! *line) { 
  333.         refresh(); 
  334.         return; 
  335.     }
  336.     Standout();      
  337.     addstr(line);
  338.     Standend();      
  339.     refresh();    
  340.     iserr = 1;
  341. }
  342.  
  343. void
  344. sel_rec (act)
  345. int        act;
  346. {
  347.     char *a, c;
  348.     int    i, m, arr[40], n;
  349.  
  350.     if (act == GTEQ || act == EQUAL) {
  351.         move (4,0); 
  352.         clrtobot();
  353.         do_error("Enter comparison values (vi-style)");
  354.         a = rel->idxs[idx]; 
  355.         m = (a[0]-'0')*100 +(a[1]-'0')*10 +(a[2]-'0');
  356.         m = min(m,39);
  357.         for (i = 0; i < m; i++) {
  358.             arr[i]= (a[i*3+3]-'0')*100 +(a[i*3+4]-'0')*10 +(a[i*3+5]-'0');
  359.             do_line (4+i, arr[i]);
  360.         }
  361.         refresh();
  362.         for (i = 0; ; ) {
  363.             move (4+i, FIRSTCOL);
  364.             switch (rel->type[arr[i]]) {
  365.             case T_CHAR:
  366.                 n=rel->siz[arr[i]]; 
  367.                 break;
  368.             case T_SHORT: case T_USHORT: 
  369.                 n=6;        
  370.                 break;
  371.             case T_LONG: case T_ULONG:  
  372.                 n=11;        
  373.                 break;
  374.             case T_FLOAT: case T_SERIAL: 
  375.                 n=11;
  376.                 break;
  377.             case T_DOUBLE: case T_MONEY:
  378.                   n=14;
  379.                   break;
  380.             case T_TIME:    
  381.                 n=8;
  382.                 break;
  383.             case T_DATE:    
  384.                 n=10;
  385.                 break;
  386.             case T_PHONE:    
  387.                 n=20;
  388.                 break;
  389.             }
  390.             if ((c=input ((char*)buf+rel->start[arr[i]], rel->type[arr[i]], n))<0)
  391.                 break;
  392.             if (c == 1)
  393.                 break;
  394.             if (c == 0 && i == m-1)  break;
  395.             if (c == 0)  c='+';
  396.             switch (c) {
  397.             case '-': case 'k': case AR_UP:    
  398.                 i--; 
  399.                 break;
  400.             case '+': case 'j': case AR_DOWN: 
  401.                 i++; 
  402.                 break;
  403.             }
  404.             if (i == -1)  i = m-1;
  405.             if (i ==  m)  i = 0;
  406.         }
  407.         if (c < 0) {
  408.             fill_page();  do_error("Search aborted");
  409.             return;
  410.         }
  411.     }
  412.  
  413.     if (mb_sel (rel, idx, buf, act, buf) != MB_OKAY) {
  414.         a = mb_error;  
  415.         fill_page();
  416.         do_error (a);
  417.         return;
  418.      }
  419.     fill_page();
  420. }
  421.  
  422. void
  423. fill_page ()
  424. {
  425. int  i, n;
  426.  
  427.     move(4, 0);  
  428.     clrtobot();
  429.  
  430.     if (rel)
  431.         for (i = 0, n = (pg-1)*ROWS; i < (pg == pgmax ? pglst : ROWS); i++, n++)
  432.             do_line(4+i, n);
  433.  
  434.     paint_scrn(-1, 0);
  435. }
  436.  
  437. #define getdata(b,f,t) sprintf (b, f, *(t *)((char *)buf +rel->start[n]));
  438.  
  439. void
  440. do_line (y, n)
  441. int        y, n;
  442. {
  443. char temp[80];
  444. int     t;
  445. long ac,pre,num,ext;
  446.  
  447.     if (n >= rel->num_f) 
  448.         return;
  449.     move (y, 0);  
  450.     clrtoeol();
  451.  
  452.     strzcpy(temp, rel->name[n], 13);
  453.     mvaddstr(y,  0, temp);
  454.     mvaddstr(y, 15, "-");
  455.  
  456.     switch (rel->type[n]) {
  457.     case T_CHAR:     
  458.         mvaddch (y, 17, '\"');
  459.         mvaddch (y, FIRSTCOL +min(rel->siz[n],60), '\"');
  460.         break;
  461.     case T_SHORT: case T_USHORT:  
  462.         mvaddstr (y, 17, "[        ]");                    
  463.         break;
  464.     case T_LONG: case T_ULONG: case T_FLOAT:    
  465.         mvaddstr (y, 17, "[              ]");             
  466.         break;
  467.     case T_DOUBLE:  
  468.         mvaddstr (y, 17, "[                  ]");         
  469.         break;
  470.     case T_MONEY:    
  471.         mvaddstr (y, 17, "$                  ");          
  472.         break;
  473.     case T_TIME:     
  474.         mvaddstr (y, 17, "(  :  :  )");
  475.         break;
  476.     case T_DATE:     
  477.         mvaddstr (y, 17, "(  /  /     )");
  478.         break;
  479.     case T_SERIAL:  
  480.         mvaddstr (y, 17, "(              )");    
  481.         break;
  482.     case T_PHONE:    
  483.         mvaddstr (y, 17, "(    -    -                )"); 
  484.         break;
  485.     }
  486.  
  487.     if (rel->pos != 0L) {
  488.         switch (rel->type[n]) {
  489.             case T_CHAR:      t = min (rel->siz[n], 60);
  490.                               strzcpy(temp, (char *)buf+rel->start[n], t);
  491.                              break;
  492.             case T_SHORT:    getdata(temp, "%d",     short);     break;
  493.             case T_USHORT:  getdata(temp, "%u",     ushort);      break;
  494.             case T_LONG:    getdata(temp, "%ld",     long);         break;
  495.             case T_ULONG:    getdata(temp, "%lu",     ulong);     break;
  496.             case T_FLOAT:    getdata(temp, "%f",     float);     break;
  497.             case T_DOUBLE:  getdata(temp, "%lf",     double);      break;
  498.             case T_MONEY:    getdata(temp, "%-.2lf", double);      break;
  499.  
  500.             case T_SERIAL:  getdata (temp, "%ld", long);        break;
  501.             case T_PHONE:    
  502.                 scn_phone(&ac,&pre,&num,&ext, ((char *)buf + rel->start[n]));
  503.                 strcpy(temp, fmt_phone (ac, pre, num, ext, 0)); 
  504.                 break;
  505.             case T_TIME:    
  506.                 strcpy(temp, fmt_time (*(mb_time *) ((char *)buf +rel->start[n]), 0)); 
  507.                 break;
  508.             case T_DATE:     
  509.                 strcpy(temp, fmt_date (*(mb_date *) ((char *)buf +rel->start[n]), 0)); 
  510.                 break;
  511.         }
  512.         fprintf(stderr, "moving %s to %d and %d\n", temp, y, FIRSTCOL);
  513.         mvaddstr (y, FIRSTCOL, temp);
  514.     }
  515. }
  516.  
  517. void
  518. add_rec (opt)
  519. int        opt;
  520. {
  521. int      i;
  522. int        _pg, n, m, o;  /* Handles up to 500 fields */
  523. mb_err    e;
  524. char    c,  *p;
  525. long    tlong;
  526.  
  527.     _pg = pg;
  528.  
  529.     if (opt) {
  530.          tlong = rel->pos;
  531.          rel->pos = 1L; 
  532.          zero_rec();  /* Add new rec */
  533.     }
  534.  
  535.     for (pg = 1, i = 0; ; ) {
  536.         fill_page ();
  537.         if (opt)  
  538.             do_error ("enter data to add");
  539.         else        
  540.             do_error ("enter new data for this record");
  541.  
  542.         for (o = ROWS*pg-ROWS, m = o + (pg == pgmax ? pglst : ROWS); ; ) {
  543.               move(4+i - ((pg-1)*ROWS), FIRSTCOL);
  544.             switch (rel->type[i]) {
  545.                 case T_CHAR:                     n=rel->siz[i];  break;
  546.                 case T_SHORT: case T_USHORT:      n=6;            break;
  547.                 case T_LONG:  case T_ULONG:        n=11;            break;
  548.                 case T_FLOAT: case T_SERIAL:      n=11;            break;
  549.                 case T_DOUBLE: case T_MONEY:    n=14;            break;
  550.                 case T_TIME:                      n=8;            break;
  551.                 case T_DATE:                    n=10;            break;
  552.                 case T_PHONE:                    n=20;            break;
  553.             }
  554.             n = min (n, 60);
  555.             if (rel->type[i] == T_SERIAL) {
  556.                 if (rel->num_f == 1)  
  557.                     c = 1;     /* Nothing but serial#?  Done. */
  558.                 else
  559.                     c = '+';  /* Don't let 'em enter serial# */
  560.             } else {
  561.                 if ((c = input ((char *)buf + rel->start[i], rel->type[i], n)) < 0)
  562.                     break;
  563.             }
  564.             if (c == 0 && i == m-1 && pg==pgmax)  c=1;
  565.             if (c == 0)  c='+';
  566.             if (c == 1)  break;
  567.             switch (c) {
  568.                  case '-': case 'k': case AR_UP:    i--;  c='-';  break;
  569.                 case '+': case 'j': case AR_DOWN: i++;  c='+';  break;
  570.             }
  571.             if (c == '-' && rel->type[i] == T_SERIAL)  i--;
  572.             if (i >=  m) { 
  573.                 pg++;
  574.                 i = m;  
  575.                 c = 0;
  576.                 if (pg > pgmax) pg = 1;
  577.                 i = 0;
  578.                 break;
  579.             }
  580.             if (i <    o) { pg--;i=o-1;c=0;if(pg==0) pg=pgmax,i=rel->num_f-1;break;}
  581.          }
  582.         if (c != 0)  break;
  583.      }
  584.     if (opt)  pg=_pg, rel->pos=tlong;
  585.  
  586.     if (c < 0)
  587.      { mb_sel (rel, idx, buf, CURRENT, NULL);  if (! rel->pos)  zero_rec();
  588.         fill_page ();
  589.         do_error ("add aborted");
  590.         return;
  591.      }
  592.  
  593.     fill_page();
  594.     do_error ("wait...");
  595.  
  596.     if (opt)  e=mb_add (rel, buf), p=mb_error;
  597.     else        e=mb_upd (rel, buf), p=mb_error;
  598.  
  599.     mb_sel (rel, idx, buf, CURRENT, NULL);  if (! rel->pos)  zero_rec();
  600.     fill_page ();
  601.  
  602.     if (e != MB_OKAY)
  603.         do_error (p);
  604.     else
  605.      { if (opt)  do_error ("record successfully added");
  606.         else        do_error ("record successfully updated");
  607.         paint_scrn (-1, 0);
  608.      }
  609. }
  610.  
  611. void
  612. del_rec ()
  613. {
  614.     if (! verify ("delete this record ? "))
  615.      { do_error ("delete aborted");
  616.         return;
  617.      }
  618.     do_error ("wait...");
  619.     if (mb_del (rel) != MB_OKAY)
  620.      { do_error (mb_error);
  621.         return;
  622.      }
  623.     if (! rel->pos)  zero_rec();
  624.     fill_page();
  625.     do_error ("record deleted");
  626. }
  627.  
  628. int
  629. verify (str)
  630. char    *str;
  631. {
  632.     char  c;
  633.     do_error (str);
  634.     for (;;)
  635.      { c = getarr();
  636.         switch (tolower(c))
  637.          { case 'q': case 'n':  case ' ':    do_error (""); return 0; break;
  638.             case  27: case '\r': case '\n':  do_error (""); return 0; break;
  639.             case 'y':                                do_error (""); return 1; break;
  640.          }
  641.      }
  642. }
  643.  
  644. void
  645. zero_rec ()
  646. {
  647. int  i;
  648. char *a;
  649.  
  650.     for (i = 0; i < rel->num_f; i++) {
  651.         a=(char *)buf +rel->start[i];
  652.         switch (rel->type[i]) {
  653.             case T_CHAR:    *a = 0;     break;
  654.             case T_PHONE:    *a = 0;     break;
  655.             case T_SHORT:    *(short  *)a = (short)0;  break;
  656.             case T_USHORT:  *(ushort *)a = (ushort)0; break;
  657.             case T_LONG:    *(long    *)a = (long)0;    break;
  658.             case T_ULONG:    *(ulong  *)a = (ulong)0;  break;
  659.             case T_FLOAT:    *(float  *)a = (float)0.0;    break;
  660.             case T_DOUBLE:
  661.             case T_MONEY:    *(double *)a = (double)0.0;  break;
  662.             case T_TIME:    *(mb_time*)a = (mb_time)0;    break;
  663.             case T_DATE:    *(mb_date*)a = (mb_date)0;    break;
  664.             case T_SERIAL:  *(long    *)a = (long)0;    break;
  665.         }
  666.     }
  667. }
  668.  
  669.