home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / CONTRIB / MBASE / MBASE50.TAR / mbase / src / form.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-10  |  12.0 KB  |  510 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.  * Special thanks go to Adrian Corston (adrian@internode.com.au) for his
  8.  * suggestions and code.  While this code is of my penning, the idea and
  9.  * style of implementation for this are direct ports from his own
  10.  * excellent work.
  11.  *
  12.  */
  13.  
  14. #include "mbase.h"
  15.  
  16. #ifndef MAXnREL
  17. #define MAXnREL 20    /* Max # of relations in any given DE form */
  18. #endif
  19. #ifndef MAXnFLD
  20. #define MAXnFLD 40    /* Max # of fields in any given DE form    */
  21. #endif
  22.  
  23. /*
  24.  * Definitions
  25.  *
  26.  */
  27.  
  28. #define LPARQ "("
  29. #define LBRCQ "{"   /* These are pulled out   */
  30. #define LBKT  '['   /* so that vi's ()/[]/{}  */
  31. #define LBRC  '{'   /* matchin works properly */
  32. #define RBRC  '}'   /* in moving through the  */
  33. #define RBKT  ']'   /* code.                  */
  34. #define RBRCQ "}"
  35. #define RPARQ ")"
  36.  
  37. #define usage() fprintf (stderr, "form: format: %sform [formname]%s",SNGCR,SNGCR)
  38.  
  39. #define comment() skip(form,";"); while(skip(form,"#")) goeol(form,NULL);
  40. #define nocolon()                 while(skip(form,"#")) goeol(form,NULL);
  41.  
  42. #define fieldopt(x) (*(options[x]))
  43. #define fieldmode(x) (*(modes[x]))
  44.  
  45. /*
  46.  * Prototypes
  47.  *
  48.  */
  49.  
  50. #ifdef LONGARGS
  51.    void  main         (int, char **);
  52.    void  parse_args   (int, char **);
  53.    void  check_data   (int);
  54.    void  check_defin  (int);
  55.    void  check_screen (int);
  56.    void  check_fields (int);
  57.    void  check_modes  (int);
  58.    void  id_field     (char *, char *);
  59.    extern void  writeit      (void);
  60. #else
  61.    void  main();
  62.    void  parse_args();
  63.    void  check_data();
  64.    void  check_defin();
  65.    void  check_screen();
  66.    void  check_fields();
  67.    void  check_modes();
  68.    void  id_field();
  69.    extern void  writeit();
  70. #endif
  71.  
  72. typedef relation *relptr;
  73. typedef char      optlist[10][40];
  74. typedef int       modelist[20];
  75.  
  76. /*
  77.  * Global Variables
  78.  *
  79.  */
  80.  
  81. char      formname[30];
  82. int       form;
  83.  
  84. ftype     gen_type;
  85. int       gen_len;
  86.  
  87. char      defins[26][50];
  88. char      displ[25][140];
  89. int       num_l, pos_y, pos_x, num_f, num_m;
  90. field     fld[MAXnFLD];
  91. int       lens[MAXnFLD];
  92. optlist  *options[MAXnFLD];
  93. modelist *modes[MAXnFLD];
  94.  
  95. int       num_r;
  96. relptr    rel[MAXnREL];
  97.  
  98. /*
  99.  * Main code
  100.  *
  101.  */
  102.  
  103. void
  104. main  (argc, argv)
  105. int    argc;
  106. char **argv;
  107. {
  108.    parse_args   (argc, argv);
  109.  
  110.    check_data   (form);
  111.    check_defin  (form);
  112.    check_screen (form);
  113.    check_fields (form);
  114.    check_modes  (form);
  115.  
  116.    close   (form);
  117.    mb_die  ();  /* Close all open relations */
  118.  
  119.    writeit ();
  120.    exit (0);
  121. }
  122.  
  123. /*
  124.  * Utilities
  125.  *
  126.  */
  127.  
  128. void
  129. parse_args (agc, agv)
  130. int         agc;
  131. char           **agv;
  132. {
  133.    while (agc > 1 && agv[1][0] == '-')
  134.     {
  135.       switch (agv[1][1])
  136.        { default:   fprintf (stderr, "unrecognized option '%s'\n", agv[1]);
  137.                     usage   ();
  138.                     exit    (1);
  139.                    break;
  140.        }
  141.  
  142.       agc--;  agv++;
  143.     }
  144.  
  145.    if (agc != 2)
  146.     { usage ();
  147.       exit  (1);
  148.     }
  149.  
  150.    strcpy (formname, agv[1]);
  151.    if (strcmp (&formname[strlen(formname)-4], ".frm"))
  152.       strcat (formname, ".frm");
  153.    if ((form = openx (formname, O_RDONLY)) < 0)
  154.     { fprintf (stderr, "cannot open form '%s'\n", formname);
  155.       exit    (2);
  156.     }
  157. }
  158.  
  159. void
  160. check_data (form)
  161. int         form;
  162. {
  163.    char  temp[80];
  164.  
  165.    comment();
  166.    num_r = 0;
  167.    if (skip(form,"data") || skip(form,"relations") || skip(form,"relation"))
  168.     {
  169.       while (! skip (form, ";"))
  170.        {
  171.          if (num_r == MAXnREL)
  172.           { fprintf (stderr, "Too many relations--see trouble.dox%s", SNGCR);
  173.             close   (form);
  174.             mb_exit (4);
  175.           }
  176.  
  177.          strcpy (temp, getword(form));
  178.          skip (form, ","); nocolon();
  179.  
  180.          if (! strcmp (&temp[strlen(temp)-4], ".rel"))
  181.             temp[strlen(temp)-4] = 0;
  182.  
  183.          if ((rel[num_r] = mb_inc (temp, 0)) == RNULL)
  184.           { fprintf (stderr, "Cannot open relation '%s' : %s\n",temp,mb_error);
  185.             close   (form);
  186.             mb_exit (4);
  187.           }
  188.          num_r++;
  189.        }
  190.       if (num_r == 0)
  191.        { fprintf (stderr,"Data keyword implies at least one relation%s",SNGCR);
  192.          close   (form);
  193.          mb_exit (5);
  194.        }
  195.     }
  196. }
  197.  
  198. void
  199. check_defin (form)
  200. int          form;
  201. {
  202.    int   i;
  203.    char  temp[80], t2[80];
  204.  
  205.    for (i = 0; i < 26; i++)  defins[i][0] = 0;
  206.  
  207.    while (skip (form, "define"))
  208.     {
  209.       strcpy (temp, getword (form));
  210.       strcpy (t2,   getword (form));
  211.  
  212.       if (strlen (temp) != 1 || t2[0] == 0)
  213.        { fprintf (stderr, "DEFINE (%s:%s) syntax error%s", temp, t2, SNGCR);
  214.          close   (form);
  215.          mb_exit (6);
  216.        }
  217.       if (defins[(i = tolower(temp[0])-'a')][0] != 0)
  218.        { fprintf (stderr, "Multiple references to DEFINE %c%s",temp[0],SNGCR);
  219.          close   (form);
  220.          mb_exit (6);
  221.        }
  222.  
  223.       strcpy  (defins[i], t2);
  224.       comment ();
  225.     }
  226. }
  227.  
  228. void
  229. check_screen (form)
  230. int           form;
  231. {
  232.    int   i, j, k;
  233.    char  temp[80], c;
  234.  
  235.    pos_y = pos_x = 0;
  236.  
  237.    if (! skip (form, "screen"))
  238.     { fprintf (stderr, "Screen{} segment must follow Data and Define%s",SNGCR);
  239.       close   (form);
  240.       mb_exit (7);
  241.     }
  242.    if (! skip (form, LBRCQ))
  243.     {
  244.       pos_y = atoi (getword (form));
  245.  
  246.       if (! skip (form, LBRCQ))
  247.        {
  248.          pos_x = atoi (getword (form));
  249.  
  250.          if (! skip (form, LBRCQ))
  251.           { fprintf (stderr, "Left brace must follow SCREEN keyword%s",SNGCR);
  252.             close   (form);
  253.             mb_exit (7);
  254.           }
  255.        }
  256.     }
  257.    goeol (form, NULL);
  258.  
  259.    num_f = 0;
  260.  
  261.    for (num_l = 0; num_l < 24; num_l++)
  262.     {
  263.       goeol (form, displ[num_l]);
  264.       if (displ[num_l][0] == RBRC)  break;
  265.  
  266.       for (;;)
  267.        {
  268.          for (i = 0; displ[num_l][i] != 0; i++)
  269.             if (displ[num_l][i] == LBKT || displ[num_l][i] == LBRC)
  270.                break;
  271.          if (displ[num_l][i] == 0)
  272.             break;
  273.  
  274.          for (j = i+1; displ[num_l][j] != 0; j++)
  275.             if ((displ[num_l][j] == RBKT && displ[num_l][i] == LBKT) ||
  276.                 (displ[num_l][j] == RBRC && displ[num_l][i] == LBRC))
  277.                break;
  278.             else
  279.                temp[j-i-1] = displ[num_l][j];
  280.          temp[j-i-1] = 0;
  281.          if (displ[num_l][j] == 0)
  282.             break;
  283.  
  284.          if (num_f == MAXnFLD)
  285.           { fprintf (stderr, "Too many fields--see trouble.dox%s", SNGCR);
  286.             close   (form);
  287.             mb_exit (8);
  288.           }
  289.  
  290.          for (k = 0; k < j-i-1; k++)
  291.             if (temp[k] == ' ' || temp[k] == '\t')
  292.                break;
  293.          temp[k] = 0;
  294.          if (k == 1)
  295.           {
  296.             k = (toupper (temp[0]) - 'A');
  297.             if (defins[k][0] == 0)
  298.              {
  299.                fprintf (stderr, "Field %c undefined%s", temp[0], SNGCR);
  300.                close   (form);
  301.                mb_exit (8);
  302.              }
  303.             strcpy (temp, defins[k]);
  304.           }
  305.  
  306.          gen_len = j-i;
  307.          id_field (fld[num_f].name, temp);
  308.          fld[num_f].type  = gen_type;
  309.          fld[num_f].y     = num_l;
  310.          fld[num_f].x     = i + ((c = displ[num_l][i]) == LBKT);
  311.          fld[num_f].len   = j-i-1;
  312.          lens[num_f]      = gen_len;
  313.  
  314.          num_f++;
  315.  
  316.          for (k = i; i <= j; i++)
  317.             displ[num_l][i] = ' ';
  318.          if (c == LBRC)
  319.           {
  320.             for (i = k; displ[num_l][i+1] != 0; i++)
  321.                displ[num_l][i] = displ[num_l][i+1];
  322.             displ[num_l][i] = 0;
  323.             i = j-1;
  324.             for ( ; displ[num_l][i+1] != 0; i++)
  325.                displ[num_l][i] = displ[num_l][i+1];
  326.             displ[num_l][i] = 0;
  327.           }
  328.        }
  329.     }
  330.    comment();
  331. }
  332.  
  333. void
  334. check_fields (form)
  335. int           form;
  336. {
  337.    char   temp[80];
  338.    int    i, j, t;
  339.  
  340.    for (i = 0; i < MAXnFLD; i++)
  341.       options[i] = (optlist *)0;
  342.  
  343.    while (skip (form, "field"))
  344.     {
  345.       id_field (temp, getword(form));
  346.  
  347.       for (i = 0; i < num_f; i++)
  348.          if (! strcmp (fld[i].name, temp))  break;
  349.       if (i == num_f)
  350.        { fprintf (stderr, "FIELD variable '%s' unused%s", temp, SNGCR);
  351.          close   (form);
  352.          mb_exit (9);
  353.        }
  354.  
  355.       skip (form, "type");
  356.  
  357.        /*
  358.         * Field credit type choice ("Yy" "Nn" "?");
  359.         * Field temp   type link to credit ("Yes" "No" "Maybe");
  360.         * Field other  type money;
  361.         *
  362.         */
  363.  
  364.       strcpy (temp, getword (form));
  365.  
  366.       if (! strcmp (temp, "choice") || ! strcmp (temp, "link"))
  367.        {
  368.          t = 0;
  369.          if (!strcmp (temp, "link"))
  370.           {
  371.             skip (form, "to");
  372.             id_field (temp, getword(form));
  373.             t = 1;
  374.           }
  375.  
  376.          if (! skip (form, LPARQ))
  377.           { fprintf (stderr, "(...) must surround options in FIELD%s", SNGCR);
  378.             close   (form);
  379.             mb_exit (9);
  380.           }
  381.  
  382.          if ((options[i] = New (optlist)) == (optlist *)0)
  383.           { fprintf (stderr, "fatal error: out of memory%s", SNGCR);
  384.             close   (form);
  385.             mb_exit (9);
  386.           }
  387.  
  388.          fieldopt(i)[0][0] = 0;  /* Link-To field name */
  389.          if (t == 1)
  390.             strcpy (fieldopt(i)[0], temp);  /* Link-To field name */
  391.  
  392.          for (j = 1; !skip (form, RPARQ); j++)
  393.           {
  394.             if (j == 10)  break;
  395.             strcpy (fieldopt(i)[j], getword(form));
  396.           }
  397.          if (j != 10)  fieldopt(i)[j][0] = 0;
  398.  
  399.          fld[i].option = t+1;  /* t: 0 == choice, 1 == link */
  400.  
  401.          comment();
  402.          continue;
  403.        }
  404.  
  405.       if (! strcmp (temp, "char"))       fld[i].type = T_CHAR;
  406.       if (! strcmp (temp, "string"))     fld[i].type = T_CHAR;
  407.       if (! strcmp (temp, "character"))  fld[i].type = T_CHAR;
  408.       if (! strcmp (temp, "short"))      fld[i].type = T_SHORT;
  409.       if (! strcmp (temp, "ushort"))     fld[i].type = T_USHORT;
  410.       if (! strcmp (temp, "long"))       fld[i].type = T_LONG;
  411.       if (! strcmp (temp, "ulong"))      fld[i].type = T_ULONG;
  412.       if (! strcmp (temp, "float"))      fld[i].type = T_FLOAT;
  413.       if (! strcmp (temp, "double"))     fld[i].type = T_DOUBLE;
  414.       if (! strcmp (temp, "money"))      fld[i].type = T_MONEY;
  415.       if (! strcmp (temp, "time"))       fld[i].type = T_TIME;
  416.       if (! strcmp (temp, "date"))       fld[i].type = T_DATE;
  417.       if (! strcmp (temp, "serial"))     fld[i].type = T_SERIAL;
  418.       if (! strcmp (temp, "phone"))      fld[i].type = T_PHONE;
  419.  
  420.       comment ();
  421.     }
  422. }
  423.  
  424. void
  425. check_modes  (form)
  426. int           form;
  427. {
  428.    char   temp[80];
  429.    int    i, j, k;
  430.  
  431.    for (i = 0; i < MAXnFLD; i++)
  432.       modes[i] = (modelist *)0;
  433.    for (i = 0; i < num_f; i++)
  434.       if ((modes[i] = New (modelist)) == (modelist *)0)
  435.        { fprintf (stderr, "fatal error: out of memory%s", SNGCR);
  436.          close   (form);
  437.          mb_exit (9);
  438.        }
  439.  
  440.    num_m = 0;
  441.  
  442.    while (skip (form, "mode"))
  443.     {
  444.       if ((i = atoi (getword (form))) < 1) { goeol (form, NULL);  continue; };
  445.  
  446.       strcpy (temp, getword (form));
  447.       k = FM_INOUT;
  448.       if (! strcmp (temp, "in"))   k = FM_IN;
  449.       if (! strcmp (temp, "out"))  k = FM_OUT;
  450.  
  451.       for (j = 0; j < num_f; j++)
  452.          fieldmode(j)[i-1] = k;
  453.  
  454.       while (! skip (form, ";"))
  455.        {
  456.          id_field (temp, getword (form));
  457.  
  458.          for (j = 0; j < num_f; j++)
  459.             if (! strcmp (fld[j].name, temp))  break;
  460.          if (j == num_f)
  461.           { fprintf (stderr, "MODE variable '%s' unused%s", temp, SNGCR);
  462.             close   (form);
  463.             mb_exit (9);
  464.           }
  465.  
  466.          k = FM_INOUT;
  467.          strcpy (temp, getword (form));
  468.          if (! strcmp (temp, "in"))   k = FM_IN;
  469.          if (! strcmp (temp, "out"))  k = FM_OUT;
  470.          fieldmode(j)[i-1] = k;
  471.  
  472.          skip (form, ",");
  473.        }
  474.  
  475.       num_m ++;
  476.       nocolon ();
  477.     }
  478.  
  479.    if (! skip (form, "end"))
  480.     { fprintf (stderr, "unexpected keyword: END%s", SNGCR);
  481.       close   (form);
  482.       mb_exit (9);
  483.     }
  484. }
  485.  
  486. void
  487. id_field (buf, str)
  488. char     *buf,*str;
  489. {
  490.    int  i, j;
  491.  
  492.    strcpy (buf, str);
  493.    gen_type = T_CHAR;
  494.  
  495.    if (strchr (str, '.') == NULL)
  496.       for (i = 0; i < num_r; i++)
  497.        {
  498.          for (j = 0; j < rel[i]->num_f; j++)
  499.             if (! strcmp (str, rel[i]->name[j]))
  500.                {
  501.                sprintf (buf, "%s.%s", rel[i]->relname, rel[i]->name[j]);
  502.                gen_type = rel[i]->type[j];
  503.                gen_len  = rel[i]->siz[j];
  504.                break;
  505.                }
  506.          if (j != rel[i]->num_f)  break;
  507.        }
  508. }
  509.  
  510.