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