home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / pp / pp-6.0 / Lib / or / or_std2or.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-18  |  4.9 KB  |  272 lines

  1. /* or_std2or.c: convert standard or representation to tree */
  2.  
  3. # ifndef lint
  4. static char Rcsid[] = "@(#)$Header: /xtel/pp/pp-beta/Lib/or/RCS/or_std2or.c,v 6.0 1991/12/18 20:23:08 jpo Rel $";
  5. # endif
  6.  
  7. /*
  8.  * $Header: /xtel/pp/pp-beta/Lib/or/RCS/or_std2or.c,v 6.0 1991/12/18 20:23:08 jpo Rel $
  9.  *
  10.  * $Log: or_std2or.c,v $
  11.  * Revision 6.0  1991/12/18  20:23:08  jpo
  12.  * Release 6.0
  13.  *
  14.  */
  15.  
  16.  
  17.  
  18. #include "or.h"
  19. #include "util.h"
  20.  
  21. extern char     or_error[];
  22. /*
  23. Input standard to form orname
  24. */
  25.  
  26. static OR_ptr    or_std2or_aux();
  27.  
  28. OR_ptr or_std2or (str)
  29. char            *str;
  30. {
  31.     OR_ptr    tree;
  32.     char    *p, tmp[BUFSIZ];
  33.     int    firstpn;
  34.     PP_DBG (("or_util.c/or_std2or (%s)", str));
  35.  
  36.     if (str == NULLCP)
  37.         return NULLOR;
  38.  
  39.     tree = NULLOR;
  40.  
  41.     if (str[0] == '/') {
  42.         /*
  43.           No implicit PN
  44.           */
  45.         firstpn = FALSE;
  46.         p = &str[1];
  47.     }
  48.     else {
  49.         firstpn = TRUE;
  50.         p = str;
  51.     }
  52.  
  53.     if ((tree = or_std2or_aux(p, '/', firstpn)) == NULLOR) {
  54.         char    *colon, *equal;
  55.         char    or_error_sav[BUFSIZ];
  56.         
  57.         (void) strcpy (or_error_sav, or_error);
  58.  
  59.         /* ignore leading semicolon */
  60.         if (str[0] == ';')
  61.             p = &str[1];
  62.         else
  63.             p = str;
  64.         
  65.         colon = index(p, ';');
  66.         equal = index(p, '=');
  67.         
  68.         if (equal == NULLCP)
  69.             /* no equals */
  70.             firstpn = TRUE;
  71.         else if (colon == NULLCP)
  72.             /* no semicolon but equals */
  73.             firstpn = FALSE;
  74.         else if (colon < equal)
  75.             /* semicolon before equals */
  76.  
  77.             firstpn = TRUE;
  78.         else
  79.             firstpn = FALSE;
  80.  
  81.         if ((tree = or_std2or_aux(p, ';', firstpn)) == NULLOR) {
  82.             (void) strcpy (or_error, or_error_sav);
  83.             return NULLOR;
  84.         }
  85.     }
  86.  
  87.     or_chk_admd(&tree);
  88.     if (or_checktypes(tree, tmp) == NOTOK) {
  89.         or_free(tree);
  90.         (void) or_lose("Bad OR Address '%s'", tmp);
  91.         return NULLOR;
  92.     }
  93.  
  94.     return tree;
  95. }
  96.  
  97. static OR_ptr    or_std2or_aux(str, sep, firstpn)
  98. char    *str;
  99. char    sep;
  100. int    firstpn;
  101. {
  102.     OR_ptr    tree = NULLOR,
  103.         or = NULLOR;
  104.     char    keybuf[LINESIZE],
  105.         valbuf[LINESIZE],
  106.         tbuf[LINESIZE],
  107.         *p,
  108.         *r;
  109.     int    ortype,
  110.         before = TRUE;
  111.  
  112.     p = str;
  113.     
  114.     for (; *p != '\0';) {
  115.         r = keybuf;
  116.         for (; *p != '\0';) {
  117.             if (*p == sep) {
  118.                 if (!firstpn) {
  119.                     (void) or_lose ("Bad AV Syntax '%s'",
  120.                             str);
  121.                     or_free (tree);
  122.                     return NULLOR;
  123.                 }
  124.                 p++;
  125.  
  126.             } else {
  127.                 switch (*p) {
  128.                     case '=':
  129.                     if (firstpn) {
  130.                         (void) or_lose ("Bad PN syntax '%s'", str);
  131.                         return NULLOR;
  132.                     }
  133.                     p++;
  134.                     break;
  135.                     case '$':
  136.                     p++;
  137.                     default:
  138.                     *r++ = *p++;
  139.                     continue;
  140.                 }
  141.             }
  142.             break;
  143.         }
  144.  
  145.         *r = '\0';
  146.  
  147.         if (firstpn) {
  148.             tree = or_buildpn (keybuf);
  149.             if (*p == '\0')
  150.                 return (tree);
  151.             firstpn = FALSE;
  152.             continue;
  153.         }
  154.  
  155.         if (*p == '\0') {
  156.             if (keybuf[0] == '\0')
  157.                 return (tree);
  158.             (void) or_lose ("Prematurely terminated OR '%s'", str);
  159.             or_free (tree);
  160.             return NULLOR;
  161.         }
  162.  
  163.         r = valbuf;
  164.  
  165.         for (; *p != '\0';) {
  166.             if (*p != sep) {
  167.                 switch (*p) {
  168.                     case '=':
  169.                     (void) or_lose("Bad AV syntax '%s'",str);
  170.                     or_free (tree);
  171.                     return NULLOR;
  172.                     case '$':
  173.                     p++;
  174.                     default:
  175.                     *r++ = *p++;
  176.                     continue;
  177.                 }
  178.             }
  179.             break;
  180.         }
  181.  
  182.         *r = '\0';
  183.  
  184.         if (*p != sep) 
  185.             PP_DBG (("Prematurely ended OR - no slash '%s'", str));
  186.         else
  187.             p++;
  188.  
  189.         PP_DBG ((
  190.              "or_util.c/or_std2or: Component '%s' = '%s'", keybuf, valbuf));
  191.  
  192.         /*
  193.           Process string from BACK to  optimise or-add
  194.           */
  195.  
  196.         switch (ortype = or_name2type (keybuf)) {
  197. #ifdef NOTDEF
  198.             case OR_C:
  199.             case OR_ADMD:
  200.             case OR_PRMD:
  201. #endif
  202.             case OR_O:
  203.             before = FALSE;
  204.             default:
  205.             break;
  206.         }
  207.  
  208.         if (ortype != NOTOK) {
  209.             or = or_new (ortype, NULLCP, valbuf);
  210.             if (or == NULLOR) return NULLOR;
  211.             if ((tree = or_add (tree, or, before)) == NULLOR)
  212.                 return NULLOR;
  213.             continue;
  214.         }
  215.  
  216.         if (lexequ (keybuf, "pn") == 0) {
  217.             OR_ptr    pntree, orp, ix = NULLOR;
  218.             pntree = or_buildpn (valbuf);
  219.             for (orp = pntree; orp != NULLOR; orp = ix) {
  220.                 ix = orp -> or_next;
  221.                 orp -> or_next = NULLOR;
  222.                 if ((tree = or_add(tree, orp, before)) == NULLOR)
  223.                     return NULLOR;
  224.             }
  225.             continue;
  226.         }
  227.  
  228.         (void) strncpy (tbuf, keybuf, 3);
  229.         tbuf[3] = '\0';
  230.  
  231.         if (((int)strlen (keybuf) > 2) && lexequ (tbuf, "dd.") == 0) {
  232.             if (!or_str_isps(valbuf)) {
  233.                 (void) or_lose("DDA '%s' is not a printable string",
  234.                     valbuf);
  235.                 or_free(tree);
  236.                 return NULLOR;
  237.             }
  238.             if (lexequ(&keybuf[3], "common") == 0) 
  239.                 or = or_new (OR_CN, NULLCP, valbuf);
  240.             else
  241.                 or = or_new (OR_DD, &keybuf[3], valbuf);
  242.             if (or == NULLOR) return NULLOR;
  243.             if ((tree = or_add (tree, or, TRUE)) == NULLOR)
  244.                 return NULLOR;
  245.             continue;
  246.         }
  247.  
  248.         /*
  249.           Might need new table if this becomes assymetrical
  250.           */
  251.  
  252.         if (or_ddvalid_chk (keybuf, &tbuf[0]) == OK) {
  253.             if (!or_str_isps(valbuf)) {
  254.                 (void) or_lose("DDA '%s' is not a printable string",
  255.                     valbuf);
  256.                 or_free(tree);
  257.                 return NULLOR;
  258.             }
  259.             or = or_new (OR_DD, tbuf, valbuf);
  260.             if (or == NULLOR) return NULLOR;
  261.             if ((tree = or_add (tree, or, TRUE)) == NULLOR)
  262.                 return NULLOR;
  263.             continue;
  264.         }
  265.  
  266.         (void) or_lose ("Unknown Key '%s'", keybuf);
  267.         or_free (tree);
  268.         return NULLOR;
  269.     }
  270.     return tree;
  271. }
  272.