home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / C / FIELD.ZIP / FIELD.C
Encoding:
C/C++ Source or Header  |  1986-05-25  |  5.8 KB  |  202 lines

  1. /*
  2.  *    field.c
  3.  *      adapted from the unix utility of the same name by :
  4.  *
  5.  *      Torensoft
  6.  *      1405 Prince of Wales
  7.  *      Suite 602
  8.  *      Ottawa ON Canada
  9.  *      K2C 3J9
  10.  *
  11.  *      Uses prototypes as defined in Ansi X3J11
  12.  */
  13.  
  14. #include <stdio.h>
  15.  
  16. #define VERSION "field V0.1"
  17. #define MAXF 3000
  18. #define MAXL 20000
  19. #define IFS '\t'
  20.  
  21.  
  22. int arguments [MAXF];     /* numerical equivalent of command line parameters */
  23. int num_columns;          /* number of columns to print */
  24. int num_fields;           /* number of fields in the current record */
  25. char *fp [MAXF];          /* pointers into line at field boundaries */
  26. char line [MAXL];         /* current line buffer */
  27. int separator = IFS;      /* the field separator */
  28. int check = FALSE;        /* true if you should check for field errors */
  29. int error = FALSE;        /* true if a check error occurs */
  30.  
  31. /* prototypes for functions in this file */
  32. void explain (char *string);
  33. int fixup (int value);
  34. void putf (int n);
  35.  
  36.  
  37. main (argcount, argvalue)
  38. int argcount;
  39. char *argvalue [];
  40. {
  41.         char *cp;
  42.         char **ap;
  43.         int  c;
  44.         int  f;          /* the field counter -- -1 initially */
  45.         int  fc;
  46.         char *parameter;   /* pointer to each command line parameter */
  47.  
  48.         num_columns = 0;
  49.         f = -1;
  50.  
  51.         if (argcount <= 1) {
  52.            explain ("no parameters selected.");
  53.         }
  54.  
  55.         /*
  56.          * read parameters into arguments.
  57.          */
  58.         while (argcount > 1) {
  59.               if (num_columns >= MAXF) {
  60.                  fprintf (stderr, "field: you cannot have more than %d fields.\n", MAXF);
  61.                  exit (1);
  62.               }
  63.               parameter = argvalue [1];
  64.               if (isdigit (parameter [0])) {
  65.                  if ((arguments [num_columns++] = atoi (parameter)) <= 0) {
  66.                     explain ("all fields are numbered from 1.");
  67.                  }
  68.  
  69.               } else if (parameter [0] == '-') {
  70.                      switch (tolower (parameter [1])) {
  71.                             case 't' : separator = fixup (parameter [2]); break;
  72.                             case 'c' : check = TRUE; break;
  73.                             default  : explain ("bad option."); break;
  74.                      }
  75.  
  76.               } else {
  77.                 explain ("all fields are numbers.");
  78.               }
  79.               argcount --; argvalue ++;
  80.         }
  81.  
  82.         if (num_columns <= 0) {
  83.            explain ("you must select at least one field.");
  84.         }
  85.  
  86.         /*
  87.          * read and copy the input.
  88.          */
  89.         num_columns --;
  90.         cp = line;
  91.         ap = fp;
  92.         *ap++ = cp;
  93.         while (1) {
  94.               c = getchar ();
  95.               if (c == '\n' || c == EOF) {
  96.                  if (cp == line && c == EOF){
  97.                     break;
  98.                  }
  99.                  *cp++ = '\0';
  100.                  num_fields = ap - fp;
  101.  
  102.                  /*
  103.                   * check to see if all lines have the same number of fields.
  104.                   * if f is negative then this is the first line we are processing.
  105.                   */
  106.                  if (f < 0) {
  107.                     f = num_fields;
  108.                  } else {
  109.                     if (f != num_fields) {
  110.                        error = TRUE;
  111.                     }
  112.                  }
  113.  
  114.                  /*
  115.                   * print this line.
  116.                   */
  117.                  for (fc = 0; fc <= num_columns; fc++) {
  118.                      putf (arguments [fc] - 1);
  119.                      if (fc != num_columns) {
  120.                         putchar (separator);
  121.                      }
  122.                  }
  123.                  if (c == EOF) {
  124.                     break;
  125.                  }
  126.                  putchar ('\n');
  127.                  cp = line;
  128.                  ap = fp;
  129.                  *ap++ = cp;
  130.               } else if (c == separator) {
  131.                  *cp++ = '\0';
  132.                  if (ap >= fp + MAXF) {
  133.                     fprintf (stderr, "field: some lines have more than %d fields in them.\n", MAXF);
  134.                     exit (1);
  135.                  }
  136.                  *ap++ = cp;
  137.               } else {
  138.                  if (cp >= line + MAXL) {
  139.                     fprintf (stderr, "field: some lines have more than %d characters in them.\n", MAXL);
  140.                     exit (1);
  141.                  }
  142.                  *cp++ = c;
  143.               }
  144.  
  145.  
  146.         }
  147.  
  148.         /*
  149.          * print the error message if we have to.
  150.          */
  151.         if (error && check) {
  152.            fprintf (stderr, "field: not all lines had the same number of fields.\n");
  153.         }
  154.  
  155.         exit (0);
  156. }
  157.  
  158.  
  159. /*
  160.  * output field n from the current line to the standard output.
  161.  */
  162.  
  163. void putf (n)
  164. int n;
  165. {
  166.         char *cp = fp [n];
  167.         int c;
  168.  
  169.         if (n < 0 || n >= num_fields) {
  170.            return;
  171.         }
  172.         while (c = *cp++) {
  173.               putchar (c);
  174.         }
  175. }
  176.  
  177. void explain (string)
  178. char *string;
  179. {
  180.         fprintf (stderr, "\n%s\n\n", string);
  181.         fprintf (stderr, "%s:\nusage: [-tc -c] n [n n ...]\n", VERSION);
  182.         fprintf (stderr, "Selects fields or columns from a file.\n");
  183.         fprintf (stderr, "Fields are numbered from 1 and a field may be requested more than once.\n");
  184.         fprintf (stderr, "Options:\n-tc\tSet the field separator to c (default TAB).\n");
  185.         fprintf (stderr, "-c\tCheck that all input records contain the same number of fields.\n\n");
  186.         exit (2);
  187. }
  188.  
  189. /*
  190.  * compensates for someone typing "-t " to get space for a separator.
  191.  * this is needed since "-t " is changed to "-t" on the command line
  192.  */
  193.  
  194. int fixup (value)
  195. int value;
  196. {
  197.         if (value == 0) {
  198.            value = ' ';
  199.         }
  200.         return (value);
  201. }