home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 5 / DATAFILE_PDCD5.iso / utilities / n / nuweb / Source / src / names_c < prev    next >
Encoding:
Text File  |  1997-03-13  |  11.6 KB  |  432 lines

  1.  
  2. #line 656 "nuweb.w"
  3. #include "global.h"
  4.  
  5. #line 3084 "nuweb.w"
  6. enum { LESS, GREATER, EQUAL, PREFIX, EXTENSION };
  7.  
  8. static int compare(char *x, char *y)
  9. {
  10.   int len, result;
  11.   int xl = strlen(x);
  12.   int yl = strlen(y);
  13.   int xp = x[xl - 1] == ' ';
  14.   int yp = y[yl - 1] == ' ';
  15.   if (xp) xl--;
  16.   if (yp) yl--;
  17.   len = xl < yl ? xl : yl;
  18.   result = strncmp(x, y, len);
  19.   if (result < 0) return GREATER;
  20.   else if (result > 0) return LESS;
  21.   else if (xl < yl) {
  22.     if (xp) return EXTENSION;
  23.     else return LESS;
  24.   }
  25.   else if (xl > yl) {
  26.     if (yp) return PREFIX;
  27.     else return GREATER;
  28.   }
  29.   else return EQUAL;
  30. }
  31.  
  32. #line 3114 "nuweb.w"
  33. char *save_string(char *s)
  34. {
  35.   char *new = (char *) arena_getmem((strlen(s) + 1) * sizeof(char));
  36.   strcpy(new, s);
  37.   return new;
  38. }
  39.  
  40. #line 3124 "nuweb.w"
  41. static int ambiguous_prefix(Name *node, char *spelling);
  42.  
  43. Name *prefix_add(Name *root[], char *spelling)
  44. {
  45.   Name *node = *root;
  46.   while (node) {
  47.     switch (compare(node->spelling, spelling)) {
  48.     case GREATER:   root = &node->rlink;
  49.                     break;
  50.     case LESS:      root = &node->llink;
  51.                     break;
  52.     case EQUAL:     return node;
  53.     case EXTENSION: node->spelling = save_string(spelling);
  54.                     return node;
  55.     case PREFIX:    
  56. #line 3153 "nuweb.w"
  57.                     {
  58.                       if (ambiguous_prefix(node->llink, spelling) ||
  59.                           ambiguous_prefix(node->rlink, spelling))
  60.                         fprintf(stderr,
  61.                                 "%s: ambiguous prefix @<%s...@> (%s, line %d)\n",
  62.                                 command_name, spelling, source_name, source_line);
  63.                     }
  64.                     
  65. #line 3138 "nuweb.w"
  66.  
  67.                     return node;
  68.     }
  69.     node = *root;
  70.   }
  71.   
  72. #line 3249 "nuweb.w"
  73.   {
  74.     node = (Name *) arena_getmem(sizeof(Name));
  75.     node->spelling = save_string(spelling);
  76.     node->mark = FALSE;
  77.     node->llink = NULL;
  78.     node->rlink = NULL;
  79.     node->uses = NULL;
  80.     node->defs = NULL;
  81.     node->tab_flag = TRUE;
  82.     node->indent_flag = TRUE;
  83.     node->debug_flag = FALSE;
  84.     *root = node;
  85.     return node;
  86.   }
  87.   
  88. #line 3143 "nuweb.w"
  89.  
  90. }
  91.  
  92. #line 3164 "nuweb.w"
  93. static int ambiguous_prefix(Name *node, char *spelling)
  94. {
  95.   while (node) {
  96.     switch (compare(node->spelling, spelling)) {
  97.     case GREATER:   node = node->rlink;
  98.                     break;
  99.     case LESS:      node = node->llink;
  100.                     break;
  101.     case EQUAL:
  102.     case EXTENSION:
  103.     case PREFIX:    return TRUE;
  104.     }
  105.   }
  106.   return FALSE;
  107. }
  108.  
  109. #line 3198 "nuweb.w"
  110. static int robs_strcmp(char *x, char *y)
  111. {
  112.   char *xx = x;
  113.   char *yy = y;
  114.   int xc = toupper(*xx);
  115.   int yc = toupper(*yy);
  116.   while (xc == yc && xc) {
  117.     xx++;
  118.     yy++;
  119.     xc = toupper(*xx);
  120.     yc = toupper(*yy);
  121.   }
  122.   if (xc != yc) return xc - yc;
  123.   xc = *x;
  124.   yc = *y;
  125.   while (xc == yc && xc) {
  126.     x++;
  127.     y++;
  128.     xc = *x;
  129.     yc = *y;
  130.   }
  131.   if (isupper(xc) && islower(yc))
  132.     return xc * 2 - (toupper(yc) * 2 + 1);
  133.   if (islower(xc) && isupper(yc))
  134.     return toupper(xc) * 2 + 1 - yc * 2;
  135.   return xc - yc;
  136. }
  137.  
  138. #line 3229 "nuweb.w"
  139. Name *name_add(Name *root[], char *spelling)
  140. {
  141.   Name *node = *root;
  142.   while (node) {
  143.     int result = robs_strcmp(node->spelling, spelling);
  144.     if (result > 0)
  145.       root = &node->llink;
  146.     else if (result < 0)
  147.       root = &node->rlink;
  148.     else
  149.       return node;
  150.     node = *root;
  151.   }
  152.   
  153. #line 3249 "nuweb.w"
  154.   {
  155.     node = (Name *) arena_getmem(sizeof(Name));
  156.     node->spelling = save_string(spelling);
  157.     node->mark = FALSE;
  158.     node->llink = NULL;
  159.     node->rlink = NULL;
  160.     node->uses = NULL;
  161.     node->defs = NULL;
  162.     node->tab_flag = TRUE;
  163.     node->indent_flag = TRUE;
  164.     node->debug_flag = FALSE;
  165.     *root = node;
  166.     return node;
  167.   }
  168.   
  169. #line 3242 "nuweb.w"
  170.  
  171. }
  172.  
  173. #line 3271 "nuweb.w"
  174. Name *collect_file_name(void)
  175. {
  176.   Name *new_name;
  177.   char name[256];
  178.   char *p = name;
  179.   int start_line = source_line;
  180.   int c = source_get();
  181.   while (isspace(c))
  182.     c = source_get();
  183.   while (isgraph(c)) {
  184.     *p++ = c;
  185.     c = source_get();
  186.   }
  187.   if (p == name) {
  188.     fprintf(stderr, "%s: expected file name (%s, %d)\n",
  189.             command_name, source_name, start_line);
  190.     exit(-1);
  191.   }
  192.   *p = '\0';
  193.   new_name = name_add(&file_names, name);
  194.   
  195. #line 3304 "nuweb.w"
  196.   {
  197.     while (1) {
  198.       while (isspace(c))
  199.         c = source_get();
  200.       if (c == '-') {
  201.         c = source_get();
  202.         do {
  203.           switch (c) {
  204.             case 't': new_name->tab_flag = FALSE;
  205.                       break;
  206.             case 'd': new_name->debug_flag = TRUE;
  207.                       break;
  208.             case 'i': new_name->indent_flag = FALSE;
  209.                       break;
  210.             default : fprintf(stderr, "%s: unexpected per-file flag (%s, %d)\n",
  211.                               command_name, source_name, source_line);
  212.                       break;
  213.           }
  214.           c = source_get();
  215.         } while (!isspace(c));
  216.       }
  217.       else break;
  218.     }
  219.   }
  220.   
  221. #line 3291 "nuweb.w"
  222.  
  223.   if (c != '@' || source_get() != '{') {
  224.     fprintf(stderr, "%s: expected @{ after file name (%s, %d)\n",
  225.             command_name, source_name, start_line);
  226.     exit(-1);
  227.   }
  228.   if (skipnl_flag && source_next() == '\n') source_get();
  229.   return new_name;
  230. }
  231.  
  232. #line 3334 "nuweb.w"
  233. Name *collect_macro_name(void)
  234. {
  235.   char name[256];
  236.   char *p = name;
  237.   int start_line = source_line;
  238.   int c = source_get();
  239.   while (isspace(c))
  240.     c = source_get();
  241.   while (c != EOF) {
  242.     switch (c) {
  243.       case '@':  
  244. #line 3367 "nuweb.w"
  245.                  {
  246.                    c = source_get();
  247.                    switch (c) {
  248.                      case '@': *p++ = c;
  249.                                break;
  250.                      case '{': 
  251. #line 3383 "nuweb.w"
  252.                                {
  253.                                  if (p > name && p[-1] == ' ')
  254.                                    p--;
  255.                                  if (p - name > 3 && p[-1] == '.' && p[-2] == '.' && p[-3] == '.') {
  256.                                    p[-3] = ' ';
  257.                                    p -= 2;
  258.                                  }
  259.                                  if (p == name || name[0] == ' ') {
  260.                                    fprintf(stderr, "%s: empty scrap name (%s, %d)\n",
  261.                                            command_name, source_name, source_line);
  262.                                    exit(-1);
  263.                                  }
  264.                                  *p = '\0';
  265.                                  return prefix_add(¯o_names, name);
  266.                                }
  267.                                
  268. #line 3372 "nuweb.w"
  269.                  
  270.                      default:  fprintf(stderr,
  271.                                        "%s: unexpected @%c in macro name (%s, %d)\n",
  272.                                        command_name, c, source_name, start_line);
  273.                                exit(-1);
  274.                    }
  275.                  }
  276.                  
  277. #line 3344 "nuweb.w"
  278.  
  279.                  break;
  280.       case '\t':
  281.       case ' ':  *p++ = ' ';
  282.                  do
  283.                    c = source_get();
  284.                  while (c == ' ' || c == '\t');
  285.                  break;
  286.       case '\n': 
  287. #line 3402 "nuweb.w"
  288.                  {
  289.                    do
  290.                      c = source_get();
  291.                    while (isspace(c));
  292.                    if (c != '@' || source_get() != '{') {
  293.                      fprintf(stderr, "%s: expected @{ after macro name (%s, %d)\n",
  294.                              command_name, source_name, start_line);
  295.                      exit(-1);
  296.                    }
  297.                    if (skipnl_flag && source_next() == '\n') source_get();
  298.                    
  299. #line 3383 "nuweb.w"
  300.                    {
  301.                      if (p > name && p[-1] == ' ')
  302.                        p--;
  303.                      if (p - name > 3 && p[-1] == '.' && p[-2] == '.' && p[-3] == '.') {
  304.                        p[-3] = ' ';
  305.                        p -= 2;
  306.                      }
  307.                      if (p == name || name[0] == ' ') {
  308.                        fprintf(stderr, "%s: empty scrap name (%s, %d)\n",
  309.                                command_name, source_name, source_line);
  310.                        exit(-1);
  311.                      }
  312.                      *p = '\0';
  313.                      return prefix_add(¯o_names, name);
  314.                    }
  315.                    
  316. #line 3412 "nuweb.w"
  317.                  
  318.                  }
  319.                  
  320. #line 3352 "nuweb.w"
  321.  
  322.       default:   *p++ = c;
  323.                  c = source_get();
  324.                  break;
  325.     }
  326.   }
  327.   fprintf(stderr, "%s: expected macro name (%s, %d)\n",
  328.           command_name, source_name, start_line);
  329.   exit(-1);
  330.   return NULL;  /* unreachable return to avoid warnings on some compilers */
  331. }
  332.  
  333. #line 3420 "nuweb.w"
  334. Name *collect_scrap_name(void)
  335. {
  336.   char name[256];
  337.   char *p = name;
  338.   int c = source_get();
  339.   while (c == ' ' || c == '\t')
  340.     c = source_get();
  341.   while (c != EOF) {
  342.     switch (c) {
  343.       case '@':  
  344. #line 3458 "nuweb.w"
  345.                  {
  346.                    c = source_get();
  347.                    switch (c) {
  348.                      case '@': *p++ = c;
  349.                                c = source_get();
  350.                                break;
  351.                      case '>': 
  352. #line 3383 "nuweb.w"
  353.                                {
  354.                                  if (p > name && p[-1] == ' ')
  355.                                    p--;
  356.                                  if (p - name > 3 && p[-1] == '.' && p[-2] == '.' && p[-3] == '.') {
  357.                                    p[-3] = ' ';
  358.                                    p -= 2;
  359.                                  }
  360.                                  if (p == name || name[0] == ' ') {
  361.                                    fprintf(stderr, "%s: empty scrap name (%s, %d)\n",
  362.                                            command_name, source_name, source_line);
  363.                                    exit(-1);
  364.                                  }
  365.                                  *p = '\0';
  366.                                  return prefix_add(¯o_names, name);
  367.                                }
  368.                                
  369. #line 3464 "nuweb.w"
  370.                  
  371.                      default:  fprintf(stderr,
  372.                                        "%s: unexpected @%c in macro name (%s, %d)\n",
  373.                                        command_name, c, source_name, source_line);
  374.                                exit(-1);
  375.                    }
  376.                  }
  377.                  
  378. #line 3429 "nuweb.w"
  379.  
  380.                  break;
  381.       case '\t':
  382.       case ' ':  *p++ = ' ';
  383.                  do
  384.                    c = source_get();
  385.                  while (c == ' ' || c == '\t');
  386.                  break;
  387.       default:   if (!isgraph(c)) {
  388.                    fprintf(stderr,
  389.                            "%s: unexpected character in macro name (%s, %d)\n",
  390.                            command_name, source_name, source_line);
  391.                    exit(-1);
  392.                  }
  393.                  *p++ = c;
  394.                  c = source_get();
  395.                  break;
  396.     }
  397.   }
  398.   fprintf(stderr, "%s: unexpected end of file (%s, %d)\n",
  399.           command_name, source_name, source_line);
  400.   exit(-1);
  401.   return NULL;  /* unreachable return to avoid warnings on some compilers */
  402. }
  403.  
  404. #line 3476 "nuweb.w"
  405. static Scrap_Node *reverse(Scrap_Node *a);      /* a forward declaration */
  406.  
  407. void reverse_lists(Name *names)
  408. {
  409.   while (names) {
  410.     reverse_lists(names->llink);
  411.     names->defs = reverse(names->defs);
  412.     names->uses = reverse(names->uses);
  413.     names = names->rlink;
  414.   }
  415. }
  416.  
  417. #line 3495 "nuweb.w"
  418. static Scrap_Node *reverse(Scrap_Node *a)
  419. {
  420.   if (a) {
  421.     Scrap_Node *b = a->next;
  422.     a->next = NULL;
  423.     while (b) {
  424.       Scrap_Node *c = b->next;
  425.       b->next = a;
  426.       a = b;
  427.       b = c;
  428.     }
  429.   }
  430.   return a;
  431. }
  432.