home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume26 / mytinfo / part02 / findterm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-12-26  |  4.6 KB  |  284 lines

  1. /* findterm.c
  2.  *
  3.  * By Ross Ridge
  4.  * Public Domain
  5.  * 92/02/01 07:29:56
  6.  *
  7.  */
  8.  
  9. #include "defs.h"
  10.  
  11. #include <ctype.h>
  12. #include <fcntl.h>
  13. #ifdef USE_STDDEF
  14. #include <sys/types.h>
  15. #endif
  16. #include <sys/stat.h>
  17.  
  18. #ifdef USE_SCCS_IDS
  19. static const char SCCSid[] = "@(#) mytinfo findterm.c 3.2 92/02/01 public domain, By Ross Ridge";
  20. #endif
  21. static int linecnt;
  22.  
  23. static int
  24. getln(f, buf, len)
  25. FILE *f;
  26. register char *buf;
  27. int len; {
  28.     register int c, i = 0;
  29.  
  30.     while((c = getc(f)) == '#') {
  31.         linecnt++;
  32.         while((c = getc(f)) != '\n')
  33.             if (c == EOF)
  34.                 return -1;
  35.     }
  36.  
  37.     while(c != '\n') {
  38.         if (c == EOF)
  39.             return -1;
  40.         if (i < len) {
  41.             i++;
  42.             *buf++ = c;
  43.         }
  44.         c = getc(f);
  45.     }
  46.  
  47.     while(isspace(*(buf-1))) {
  48.         buf--;
  49.         i--;
  50.     }
  51.  
  52.     *buf = '\0';
  53.     return i;
  54. }
  55.  
  56. static int
  57. _findterm2(name, file, buf)
  58. char *name, *buf;
  59. char *file; {
  60.     char line[MAX_LINE];
  61.     FILE *f;
  62.     register char *sp, *dp;
  63.     int c;
  64.     int l;
  65.     int cont;
  66.     int fd;
  67.     struct stat st;
  68.  
  69.     linecnt = 0;
  70.  
  71. #ifdef DEBUG
  72.     printf("open: %s\n", file);
  73. #endif
  74.     fd = open(file, O_RDONLY);
  75.     if (fd == -1)
  76.         return -1;
  77.     if (fstat(fd, &st) == -1) {
  78.         close(fd);
  79.         return -1;
  80.     }
  81.     if ((st.st_mode & 0170000) == 0040000) {
  82.         sprintf(buf, "%s/%c/%s", file, name[0], name);
  83.         close(fd);
  84.         fd = open(buf, O_RDONLY);
  85.         if (fd == -1)
  86.             return -1;
  87.         if (read(fd, buf, MAX_BUF) < 12
  88.             || buf[0] != 032 || buf[1] != 1) {
  89.             close(fd);
  90.             return -1;
  91.         }
  92.         close(fd);
  93.         return 3;
  94.     }
  95.     f = fdopen(fd, "r");
  96.     if (f == NULL) {
  97.         close(fd);
  98.         return -1;
  99.     }
  100.  
  101.     while ((l = getln(f, buf, MAX_LINE)) != -1) {
  102.         linecnt++;
  103.         if (!isspace(buf[0]) && l != 0) {
  104.             sp = buf + l - 1;
  105.             cont = 0;
  106.             switch(*sp) {
  107.             case '\\':
  108.                 cont = 1;
  109.                 *sp = '\0';
  110.                 /* FALLTHROUGH */
  111.             case ':':
  112.                 sp = buf;
  113.                 dp = line;
  114.                 while (*sp != ':') {
  115.                     if (*sp == '\0' && cont &&
  116.                         (l = getln(f, buf, MAX_LINE))
  117.                          != -1) {
  118.                         linecnt++;
  119.                         sp = buf;
  120.                         if (l > 0 && buf[l-1] == '\\')
  121.                             cont = 1;
  122.                         else
  123.                             cont = 0;
  124.                         continue;
  125.                     }
  126.                     if (*sp == '\0') {
  127. #ifdef DEBUG
  128.                         printf("bad line (%d)\n",
  129.                                linecnt);
  130.                         fclose(f);
  131.                         return -2;
  132. #else
  133.                         goto err;
  134. #endif
  135.                     }
  136.                     *dp++ = *sp++;
  137.                 }
  138.                 *dp = '\0';
  139.                 if (!_tmatch(line, name))
  140.                     break;
  141.                 if (!cont) {
  142.                     fclose(f);
  143.                     return 1;
  144.                 }
  145.                 l = strlen(buf);
  146.                 dp = buf + l;
  147.                 while((c = getc(f)) != EOF && l < MAX_BUF) {
  148.                     if (c == '\n')
  149.                         break;
  150.                     if (c == '\\') {
  151.                         c = getc(f);
  152.                         if (c == EOF)
  153.                             break;
  154.                         if (c == '\n') {
  155.                             c = getc(f);
  156.                             if (c == EOF)
  157.                                 break;
  158.                             if (c == '#') {
  159.                                 while((c = getc(f)) != EOF && c != '\n');
  160.                                 if (c == EOF)
  161.                                     break;
  162.                                 continue;
  163.                             }
  164.                             *dp++ = c;
  165.                             continue;
  166.                         }
  167.                         *dp++ = '\\';
  168.                         *dp++ = c;
  169.                         continue;
  170.                     } 
  171.                     *dp++ = c;
  172.                 }
  173.                 *dp = '\0';
  174.                 fclose(f);
  175.                 return 1;
  176.             case ',':
  177.                 sp = buf;
  178.                 dp = line;
  179.                 while(*sp != ',')
  180.                     *dp++ = *sp++;
  181.                 *dp = '\0';
  182.                 if (!_tmatch(line, name))
  183.                     break;
  184.                 dp = buf + l;
  185.                 while ((c = getc(f)) != EOF && l < MAX_BUF) {
  186.                     if (c == '\n') {
  187.                         c = getc(f);
  188.                         if (isspace(c))
  189.                             continue;
  190.                         if (c == '\n') {
  191.                             ungetc(c, f);
  192.                             continue;
  193.                         }
  194.                         if (c == '#') {
  195.                             while((c = getc(f)) != EOF)
  196.                                 if (c == '\n')
  197.                                     break;
  198.                             if (c == EOF)
  199.                                 break;
  200.                             ungetc(c, f);
  201.                             continue;
  202.                         }
  203.                         break;
  204.                     }
  205.                     *dp++ = c;
  206.                     l++;
  207.                 }
  208.                 *dp = '\0';
  209.                 fclose(f);
  210.                 return 2;
  211.             default:
  212.             err:
  213. #ifdef DEBUG
  214.                 printf("strange line (%d)\n", linecnt);
  215. #endif
  216.                 break;
  217.             }
  218.         }
  219.     }
  220.     fclose(f);
  221.     return 0;
  222. }
  223.  
  224. int
  225. _findterm(name, path, buf)
  226. char *name;
  227. struct term_path *path;
  228. char *buf; {
  229.     register char *s, *d;
  230.     int r = 0;
  231.     while(path->file != NULL) {
  232.         switch(path->type) {
  233.         case 0:
  234.             r = _findterm2(name, path->file, buf);
  235.             break;
  236.         case 1:
  237.             if (path->file[0] == '/') {
  238.                 r = _findterm2(name, path->file, buf);
  239.             } else {
  240.                 s = path->file;
  241.                 d = buf;
  242.                 while(*s != '\0' && *s != ':')
  243.                     *d++ = *s++;
  244.                 *d = '\0';
  245.                 if (_tmatch(buf, name)) {
  246.                     while(*s != '\0')
  247.                         *d++ = *s++;
  248.                     return 1;
  249.                 }
  250.                 r = 0;
  251.             }
  252.             break;
  253.         case 2:
  254.             if (path->file[0] == '/') {
  255.                 r = _findterm2(name, path->file, buf);
  256.             } else {
  257.                 s = path->file;
  258.                 d = buf;
  259.                 while(*s != '\0' && *s != ',')
  260.                     *d++ = *s++;
  261.                 *d = '\0';
  262.                 if (_tmatch(buf, name)) {
  263.                     while(*s != '\0')
  264.                         *d++ = *s++;
  265.                     return 2;
  266.                 }
  267.                 r = 0;
  268.             }
  269.             break;
  270.         default:
  271.             r = 0;
  272.             break;
  273.         }
  274.         if (r == 1 || r == 2 || r == 3) {
  275. #ifdef DEBUG
  276.             printf("found in %s\n", path->file);
  277. #endif
  278.             break;
  279.         }
  280.         path++;
  281.     }
  282.     return r;
  283. }
  284.