home *** CD-ROM | disk | FTP | other *** search
/ Hall of Fame / HallofFameCDROM.cdr / open / head.lzh / HEAD.C next >
C/C++ Source or Header  |  1986-01-21  |  9KB  |  282 lines

  1. /* Program HEAD -- prints first 'n' lines of files */
  2. /* (C) Copyright John S. Simonson 1985, 1986 All Rights Reserved. */
  3. /* Version (major.minor) 1.4    --revised 1-6-86                  */
  4. /* Version 2.1 Microsoft C version    --  1-17-86                 */
  5. #include <types.h>
  6. #include <stat.h>
  7. #include <stdio.h>
  8. #include <ctype.h>
  9. #define TRANS 1
  10. #define HEDR  2
  11. #define LINES 3
  12. #define NUMBR 4
  13. #define DUD   6
  14. #define FSPEC 0
  15. #define TRUE  1
  16. #define FALSE 0
  17. #define DASH '-'
  18. #define SLASH '/'
  19. #define DEFAULT 5
  20. #define MARKLEN 7
  21. #define FEED 5
  22. #define MAXSTR 255
  23. #define MAJOR 2
  24. #define MINOR 1
  25. short i,k,j,m; 
  26. unsigned short nlin;  /* this will be the Number of LINes to print     */
  27. char a[MAXSTR];
  28. char mark[MARKLEN]; /* array to hold options switch settings */
  29. char *x;
  30. short nbad;
  31. char told;
  32. char cpyrite[80];
  33.  
  34. main(ac,av)
  35. unsigned ac;   /* argument count */
  36. char *av[];    /* argument vector -- array of pointers to args */
  37.  
  38. {
  39. strcpy(cpyrite,"(C)Copyright 1985 by John S. Simonson. All rights reserved.");
  40. nbad=0;          /* set # of bad arguments to zero */
  41. told=FALSE;      /* we haven't told user of errors */
  42. for(i=0;i<MARKLEN;i++)
  43.   mark[i] = FALSE; /* set all option switches to off */
  44. if(ac>1)
  45.   {
  46.   i=1;  /*get first true argument (not prog name)*/
  47.   while(i<ac)
  48.     {
  49.     strcpy(a,av[i]);
  50.     x=a;  /* set pointer x to array a so can pass to isnumbr easily */
  51.     if(((a[0]==DASH)||(a[0]==SLASH))&&(strlen(a)>1))
  52.       {
  53.       for(k=1;k<strlen(a);k++)
  54.         {
  55.         a[k]=tolower(a[k]); /* convert args to lower case */
  56.         if(a[k]=='t')
  57.           mark[TRANS]=TRUE;   /*drop ascii > 127d to printable form*/
  58.         else
  59.           if(a[k]=='l')
  60.             mark[LINES]=TRUE;   /*print line number selected*/
  61.           else
  62.             if(a[k]=='h')
  63.               mark[HEDR]=TRUE;  /*print file name header selected */
  64.             else
  65.               if(a[k]=='n')
  66.                 mark[FEED]=TRUE; /*add a newline to end of string*/
  67.               else
  68.                 if(isdigit(a[k]))
  69.                   {
  70.                   x=x+k; /*set *x equal to start of num string*/
  71.                   j=getlenn(x); /*find num. string length*/
  72.                   if(j>0) m=getnmbr(j,x);
  73.                   else nlin=DEFAULT; /*if not a num str, use default*/
  74.                   if(m==0) m=DEFAULT;
  75.                   if(m<0) nlin=m*(-1); /*ensure we have a posnum*/
  76.                     else  nlin=m;
  77.                   mark[NUMBR]=TRUE; /*indicate we did reset value*/
  78.                   k=k+j-1;
  79.                   x=a; /*restore x pointer to a[0]*/
  80.                   }
  81.                 else
  82.                   {
  83.                   nbad++;           /* increment n of bad args */
  84.                   mark[DUD]=i;     /*not a number, so unknown option*/
  85.                   }
  86.             }
  87.         }
  88.         else
  89.           mark[FSPEC]++;  /*no leading dash, so must be a file name*/
  90.        i++;
  91.        }
  92.     }
  93.   else
  94.     if(!told)
  95.       {
  96.       usage();
  97.       told=TRUE;
  98.       }
  99.   if(ac>1)
  100.   {
  101.   if(!mark[NUMBR])
  102.     nlin=DEFAULT;   /*if not set, set to default # of lines*/
  103.   if(mark[DUD])
  104.     {
  105.     printf("\nUnknown option %s ignored.",av[(mark[DUD])]);
  106.     printf("\n%d unknown options detected.\n",nbad);
  107.     }
  108.   if(mark[FSPEC])
  109.     crunchit(ac,av);
  110.   else
  111.     printf("\nUsage: HEAD filespec [options] --no filespec given!");
  112.   }
  113.   else
  114.     if(!told)
  115.      {
  116.      usage();
  117.      told=TRUE;
  118.      }
  119. } /* End of Main Procedure */
  120.  
  121. usage()
  122. /* this just displays how to use the program correctly */
  123. {
  124.  printf("\nUsage: HEAD filespec [-t -h -l -n -#] or [-thln#]\n");
  125.  printf("t = Translate down 128 (decimal) ascii chars over 127d\n");
  126.  printf("h = print a file Header before each file's output\n");
  127.  printf("l = print Line numbers with each line\n");
  128.  printf("n = terminate each output string with a Newline\n");
  129.  printf("# = set number of lines to print from each file to #,\n");
  130.  printf("where # is a positive integer (e.g. -10 to print ten lines)\n");
  131.  printf("\n%s Version %d.%d\n",cpyrite,MAJOR,MINOR);
  132. }
  133.  
  134. getlenn(s)
  135. char *s;
  136. /* ---------------------------------------------- */
  137. /* finds the length of s substring of numeric vals*/
  138. /* i.e., number of consecutive digits in a string */
  139. /* since the first char MUST be a digit for this  */
  140. /* to be called, we wont do error checking..and j,*/
  141. /* the return value, must be at least 1           */
  142. /*  getlenn(s) s is a pointer of type char        */
  143. /*  and j, the return value is type short         */
  144. /* ---------------------------------------------- */
  145. {
  146. char b;
  147. short j,n,m;
  148. n=strlen(s); /*get possible length of numeric string*/
  149. j=0;         /* set initial values*/
  150. m=1;
  151. b=*s;        /*char b is current char of string*/
  152. while((m<=n)&&(isdigit(b)))
  153.   {
  154.   if(isdigit(b)) j++;  /*incr length of digit chars*/
  155.   m++;  /*incr pointer to next char*/
  156.   if(m<=n) b=*(++s); /*if past possible length we stop*/
  157.   else b=32; /* set b to bogus value so its not stuck as a digit*/
  158.   }
  159. return j; 
  160. }
  161.  
  162. getnmbr(l,s)
  163. short l;
  164. char *s;
  165. /* --------------------------------------------- */
  166. /* extracts and converts a numeric substring from*/
  167. /* a string.  The integer result is returned in  */
  168. /* the type short variable "result".             */
  169. /* getnumbr(l,s) l is type short, must be >1, and*/
  170. /* less than the length of the passed string, s  */
  171. /* s is a pointer of type char.                  */
  172. /* --------------------------------------------- */
  173. {
  174. char *y;
  175. char hold[256];
  176. short result;
  177. strncpy(hold,s,l);    /*extract the portion of s we need*/
  178. y=hold;               /*let y point to our new string*/
  179. result=atoi(y);       /*convert to an integer*/
  180. return result;
  181. }
  182.  
  183. crunchit(ac,av)
  184. /*                                                   */
  185. /*---------------------------------------------------*/
  186. /* cant really think of a good name for this routine */
  187. /* this is the actual get-down-and-get-dirty section */
  188. /* that expands the file specs (if there are wild    */
  189. /* cards) and processes each matching file.          */
  190. /* The options (-t,-l,-#,-h,and file name should all */
  191. /* be available to this routine.                     */
  192. /* John Simonson 12/10/85                            */
  193. /* Microsoft C ver. 3.00 using SLIBC libarary        */
  194. /* 01/21/86                                          */
  195. /*---------------------------------------------------*/
  196. /* Note: command parsing and error checking (with the*/
  197. /*       exception that file name validity hasnt been*/
  198. /*       checked) should be done prior to entry.     */
  199. /*---------------------------------------------------*/
  200. /*                                                   */
  201. unsigned ac;
  202. char *av[];
  203. {
  204. extern FILE *fopen();
  205. FILE *ptr;
  206. char *next;
  207. char *first;
  208. char works[MAXSTR];          /* this is a string work area           */
  209. unsigned char ubuf[4096];    /* this is a HUGE string buffer */
  210. unsigned int buflen;
  211. int how=0;
  212. int result=0;
  213. int ii=0;
  214. unsigned short lineno=1;
  215. unsigned short blen=0;
  216. unsigned short retval=0;
  217. unsigned short bufptr=0;
  218. struct stat buf;             /* this needs stuff in STAT.H */
  219.  
  220.   buflen = 4096; /* now set buffer length  */
  221.   for(ii=1;ii<ac;ii++)
  222.     {
  223.     strcpy(works,av[ii]);
  224.     next=works;
  225.     if(works[0]!=DASH&&works[0]!=SLASH)
  226.       {
  227.       result=stat(next,&buf);
  228.       if(result==-1)
  229.         printf("HEAD: Could not find any file %s\n",next);
  230.       else
  231.       if(buf.st_mode & S_IFREG)
  232.       {
  233.       if (mark[HEDR])
  234.         {
  235.         printf("\n\n====================> "); /*file header requested*/
  236.         printf("%s",next);
  237.         printf(" <====================\n");
  238.         }
  239.       ptr = fopen(next,"r");  /* open the current file for read only */
  240.       if(!ptr)
  241.         {
  242.         printf("HEAD: file opening failure for %s\n",next);
  243.         how = fclose(ptr);   /* make sure file closed properly */
  244.         clearerr(ptr);       /*and clear the error condition*/
  245.         }
  246.       else
  247.         {
  248.         for(lineno=1;lineno<=nlin;lineno++)
  249.            {
  250.            first=ubuf;
  251.            first=fgets(ubuf,buflen,ptr); /*put some stuff in the buffer*/
  252.            retval=feof(ptr);  /* end-of-file ? */
  253.            if(!retval)
  254.              {
  255.              if(mark[TRANS])
  256.                {
  257.                blen=strlen(ubuf);
  258.                for(bufptr=0;bufptr<=blen;bufptr++)
  259.                  if(ubuf[bufptr]>127)
  260.                    ubuf[bufptr]=ubuf[bufptr]-128;  /* shift down */
  261.                }
  262.              if(mark[LINES])
  263.                printf("%04d: ",lineno);
  264.              if(mark[FEED])
  265.                printf("%s\n",ubuf); /* print line with newline */
  266.              else 
  267.              printf("%s",ubuf); /*print line w/o newline */
  268.              }
  269.            else
  270.            lineno=nlin+1; /*EOF, so end looping now*/
  271.            }
  272.            if(ptr) 
  273.             {
  274.             how=fclose(ptr);      /* be sure to close file */
  275.             clearerr(ptr);        /*and clear any error condition*/
  276.             }
  277.          }
  278.        }
  279.     }
  280.  }
  281.  return;
  282. }