home *** CD-ROM | disk | FTP | other *** search
/ Gold Fish 3 / goldfish_volume_3.bin / files / text / misc / cvt / source / flist.c < prev    next >
C/C++ Source or Header  |  1994-05-28  |  5KB  |  289 lines

  1. /*                                                               -*- C -*-
  2.  *  FLIST.C
  3.  *
  4.  *  (c)Copyright 1992-93 by Tobias Ferber,  All Rights Reserved.
  5.  */
  6.  
  7. #include <ctype.h>
  8. #include <string.h>
  9. #include <stdlib.h>
  10. #include <stdio.h>
  11.  
  12. #include "cvt.h"
  13.  
  14. /*** / GLOBALS / ***/
  15.  
  16. int global_numfiles= 0;
  17. fnode_t *flist= NIL(fnode_t);
  18.  
  19.  
  20. int chain_fname(char *host, char *fname)
  21. {
  22.   static fnode_t *tail= NIL(fnode_t);
  23.   fnode_t *fn;
  24.  
  25.   if( fn= (struct fnode *)malloc(sizeof(struct fnode)) )
  26.   {
  27.     if( fn->filename= (char *)malloc((strlen(fname)+1)*sizeof(char)) )
  28.     {
  29.       strcpy(fn->filename, fname);
  30.       fn->hostname= host;
  31.       fn->next= NIL(fnode_t);
  32.  
  33.       if(!flist)
  34.         flist= fn;
  35.  
  36.       if(tail)
  37.         tail->next= fn;
  38.  
  39.       tail= fn;
  40.       ++global_numfiles;
  41.     }
  42.     else
  43.     {
  44.       free(fn);
  45.       fn= NIL(fnode_t);
  46.     }
  47.   }
  48.   return fn ? 0:1;
  49. }
  50.  
  51.  
  52. void purge_flist(void)
  53. {
  54.   while(flist)
  55.   {
  56.     fnode_t *t= flist;
  57.     flist= flist->next;
  58.  
  59.     if(t->filename)
  60.       free(t->filename);
  61.     free(t);
  62.   }
  63.   global_numfiles= 0;
  64. }
  65.  
  66.  
  67. int get_fname(FILE *fp, char *fname)
  68. {
  69.   int c, n=0;
  70.   static int line= 1;
  71.  
  72.   typedef enum { outer_mode,
  73.                  word_mode,
  74.                  string_mode,
  75.                  return_mode,
  76.                  error_mode
  77.                } smode_t;
  78.  
  79.   smode_t smode= outer_mode;
  80.  
  81.   while( smode != return_mode && smode != error_mode && !feof(fp) )
  82.   {
  83.     c= fgetc(fp);
  84.  
  85.     if(feof(fp) && c!=EOF)
  86.       c= EOF;
  87.  
  88.     switch(c)
  89.     {
  90.       case ' ': case '\t':
  91.         switch(smode)
  92.         {
  93.           case word_mode:
  94.             fname[n++]= '\0';
  95.             smode= return_mode;
  96.             break;
  97.  
  98.           case string_mode:
  99.             fname[n++]= c;
  100.             break;
  101.  
  102.           case outer_mode:
  103.           case return_mode:
  104.           case error_mode:      
  105.             break;
  106.         }
  107.         break;
  108.  
  109.       case '\n': case '\r':
  110.         switch(smode)
  111.         {
  112.           case word_mode:
  113.             fname[n++]= '\0';
  114.             smode= return_mode;
  115.             break;
  116.  
  117.           case string_mode:
  118.             sprintf(fname,"%d: unterminated string at EOL; missing quotes",line);
  119.             smode= error_mode;
  120.             break;
  121.  
  122.           case outer_mode:
  123.           case return_mode:
  124.           case error_mode:      
  125.             break;
  126.         }
  127.         line++;
  128.  
  129.         { int d= fgetc(fp);
  130.           if(!( (c=='\n' && d=='\r') || (c=='\r' && d=='\n') ))
  131.             ungetc(d,fp);
  132.         }
  133.         break;
  134.  
  135.       case '\"':
  136.         switch(smode)
  137.         {
  138.           case outer_mode:
  139.             smode= string_mode;
  140.             break;
  141.  
  142.           case string_mode:
  143.             fname[n++]= '\0';
  144.             smode= return_mode;
  145.             break;
  146.  
  147.           case word_mode:
  148.             fname[n++]= '\0';
  149.             ungetc(c,fp);
  150.             smode= return_mode;
  151.             break;
  152.  
  153.           case return_mode:
  154.           case error_mode:      
  155.             break;
  156.         }
  157.         break;
  158.  
  159.       case EOF:
  160.         switch(smode)
  161.         {
  162.           case word_mode:
  163.             if( feof(fp) )
  164.             {
  165.               fname[n++]= '\0';
  166.               smode= return_mode;
  167.             }
  168.             else fname[n++]= c;
  169.             break;
  170.  
  171.           case string_mode:
  172.             if( feof(fp) )
  173.             {
  174.               sprintf(fname,"%d: unterminated string at EOF",line);
  175.               smode= error_mode;
  176.             }
  177.             else fname[n++]= c;
  178.             break;
  179.  
  180.           case outer_mode:
  181.           case return_mode:
  182.           case error_mode:      
  183.             break;
  184.         }
  185.         break;
  186.  
  187.       default:
  188.         switch(smode)
  189.         {
  190.           case outer_mode:
  191.             smode= word_mode;
  192.             /* fall through */
  193.  
  194.           case word_mode:
  195.           case string_mode:
  196.             fname[n++]= c;
  197.             break;
  198.  
  199.           case return_mode:
  200.           case error_mode:      
  201.             break;
  202.         }
  203.         break;
  204.     }
  205.  
  206.     if(n >= MAXIMUM_PATHNAME_LENGTH)
  207.     {
  208.       sprintf(fname,"%d: line too long",line);
  209.       smode= error_mode;
  210.     }
  211.   }
  212.  
  213.   fname[n]= '\0';
  214.   return (smode == error_mode) ? 0 : line;
  215. }
  216.  
  217.  
  218. int read_flist(char *host)
  219. {
  220.   char *fname;
  221.  
  222.   if( fname= (char *)malloc(MAXIMUM_PATHNAME_LENGTH * sizeof(char)) )
  223.   {
  224.     FILE *fp, *tf;
  225.  
  226.     if( fp= fopen(host, "r") )
  227.     {
  228.       int line= 1;
  229.  
  230.       while( line > 0 && !feof(fp) && !ferror(fp) )
  231.       {
  232.         line= get_fname(fp, fname);
  233.  
  234.         if(*fname)
  235.         {
  236.           if(line > 0)
  237.           {
  238.             if( global_checkexists )
  239.             {
  240.               if( tf= fopen(fname,"r") )
  241.                 fclose(tf);
  242.  
  243.               else
  244.               { echo("In file `%s' line %d:",host,line);
  245.                 perror(fname);
  246.                 return 3;
  247.               }
  248.             }
  249.  
  250.             if( chain_fname(host,fname) )
  251.             { echo("%s: ran out of memory in line %d",host,line);
  252.               return 4;
  253.             }
  254.           }
  255.           else
  256.           { echo("%s: %s",host,fname);
  257.             return 2;
  258.           }
  259.         }
  260.         /* else feof(fp) ?! */
  261.       }
  262.       fclose(fp);
  263.     }
  264.     free(fname);
  265.     return 0;
  266.   }
  267.   perror(host);
  268.   return 1;
  269. }
  270.  
  271.  
  272. #ifdef DEBUG
  273. void print_flist(void)
  274. {
  275.   fnode_t *fn= flist;
  276.  
  277.   if(fn)
  278.   {
  279.     int n;
  280.     printf("list of input files:\n");
  281.  
  282.     for(n=0; fn; n++, fn= fn->next)
  283.       printf("\t%s: \"%s\"\n", (fn->hostname ? fn->hostname
  284.                                              : "command-line"), fn->filename);
  285.   }
  286.   else printf("no input files specified.\n");
  287. }
  288. #endif /* DEBUG */
  289.