home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 1 / FFMCD01.bin / bbs / libdisks / d700t799 / disk774.lha / ExtraCmds / src / Head.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-12-05  |  7.5 KB  |  287 lines

  1. /*
  2.  * Head - Display first few lines of specified files.
  3.  *
  4.  * Version 37.1 =TP= 11-Feb-92
  5.  *
  6.  * Compile with SAS/C 5.10 and link without startup code:
  7.  *      lc -cqfist -v -b0 -rr -O -ms Head
  8.  *      blink Head.o to Head sd sc
  9.  *      protect Head +p
  10.  *
  11.  * Copyright (c) 1992 Torsten Poulin
  12.  *
  13.  * Torsten Poulin
  14.  * Banebrinken 99, 2, lejlighed 77
  15.  * DK 2400  København NV
  16.  * DENMARK
  17.  */
  18.  
  19. /****** English:HEAD ******************************************************
  20. *
  21. *   FORMAT
  22. *       HEAD [[FROM] <files|patterns>] [TO <file>] [NUMBER <n>]
  23. *
  24. *   TEMPLATE
  25. *       FROM/M,TO/K,NUM=NUMBER/N/K
  26. *
  27. *   PURPOSE
  28. *       To display first few lines of specified files.
  29. *
  30. *   SPECIFICATION
  31. *       Head copies the first NUMBER lines of each FROM file to the
  32. *       default output or the TO file if one is given.  If no FROM
  33. *       files are given, Head copies lines from the default input.
  34. *       The default number of lines is 10.
  35. *
  36. *       When more than one file is specified, the start of each
  37. *       file looks like:
  38. *
  39. *               ==>filename<==
  40. *
  41. *   EXAMPLE
  42. *       A way to display a set of short files, identifying each
  43. *       one, is:
  44. *
  45. *           1> HEAD filename1 filename2 NUMBER 9999
  46. *
  47. *   SEE ALSO
  48. *       CONCAT, TAIL, TYPE
  49. *
  50. *   UNIX EQUIVALENT
  51. *       head(BU_CMD)
  52. *
  53. ***************************************************************************
  54. *
  55. */
  56. /****** dansk:HEAD ********************************************************
  57. *
  58. *   FORMAT
  59. *       HEAD [[FROM] <filer|mønstre>] [TO <fil>] [NUMBER <n>]
  60. *
  61. *   SKABELON
  62. *       FROM/M,TO/K,NUM=NUMBER/N/K
  63. *
  64. *   FORMÅL
  65. *       At vise de første få linjer af de angivne filer.
  66. *
  67. *   SPECIFIKATION
  68. *       Head kopierer de første NUMBER linjer fra hver FROM-fil
  69. *       til sit standardoutput eller, hvis en fil er angivet med
  70. *       TO, til den.  Hvis ingen filer er angivet med FROM,
  71. *       kopierer Head linjer fra sit standardinput.  Angives der
  72. *       ikke noget antal linjer med NUMBER, vises 10.
  73. *
  74. *       Når mere end én fil angives, markeres begyndelsen af hver
  75. *       fil således:
  76. *
  77. *               ==>filnavn<==
  78. *
  79. *   EKSEMPEL
  80. *       En måde at vise en samling korte filer, med deres navne,
  81. *       er:
  82. *
  83. *           1> HEAD filnavn1 filnavn2 NUMBER 9999
  84. *
  85. *   SE OGSÅ
  86. *       CONCAT, TAIL, TYPE
  87. *
  88. *   TILSVARENDE I UNIX
  89. *       head(BU_CMD)
  90. *
  91. ***************************************************************************
  92. *
  93. */
  94.  
  95. #include <exec/types.h>
  96. #include <exec/memory.h>
  97. #include <dos/dos.h>
  98. #include <dos/dosasl.h>
  99. #include <clib/dos_protos.h>
  100. #include <clib/exec_protos.h>
  101. #include <stdio.h>
  102. #include <string.h>
  103.  
  104. #ifdef __SASC
  105. #include <pragmas/dos_pragmas.h>
  106. #include <pragmas/exec_pragmas.h>
  107. #endif
  108.  
  109. #define MAXNAMELEN 256L
  110.  
  111. #define TEMPLATE "FROM/M,TO/K,NUM=NUMBER/N/K"
  112.  
  113. #define OPT_FROM 0
  114. #define OPT_TO   1
  115. #define OPT_NUM  2
  116.  
  117.  
  118. char const *version = "\0$VER: Head 37.1 (11.2.92) ©1992 Torsten Poulin";
  119.  
  120.  
  121. static LONG Head(struct Library *SysBase, struct DosLibrary *DOSBase,
  122.                  BPTR out, UBYTE *filename, LONG num, BOOL names);
  123.  
  124.  
  125. LONG entrypoint(VOID)
  126. {
  127.     struct Library       *SysBase;
  128.     struct DosBase       *DOSBase;
  129.     struct RDArgs        *args;
  130.     struct AnchorPath    *ap;
  131.     LONG                 arg[3];
  132.     LONG                 rc = RETURN_OK;
  133.     LONG                 num = 10L;
  134.     UBYTE                **name;
  135.     UBYTE                *filename;
  136.     BPTR                 out;
  137.     LONG                 several = 0L;
  138.     
  139.     SysBase = *(struct Library **) 4L;
  140.     if(!(DOSBase = (struct DosLibrary *) OpenLibrary("dos.library", 37L)))
  141.         goto noDOS;
  142.     
  143.     arg[OPT_FROM] = arg[OPT_TO] = arg[OPT_NUM] = 0L;
  144.     
  145.     out = Output();
  146.     
  147.     if(args = ReadArgs(TEMPLATE, arg, NULL))
  148.     {
  149.         if(arg[OPT_NUM])
  150.         {
  151.             num = *(ULONG *) arg[OPT_NUM];
  152.             if(num < 1L) 
  153.                 num = 1L;
  154.         }
  155.                 
  156.         if(arg[OPT_TO] && !(out = Open((UBYTE *) arg[OPT_TO], MODE_NEWFILE)))
  157.         {
  158.             LONG err = IoErr();
  159.             PrintFault(err, (UBYTE *) arg[OPT_TO]);
  160.             rc = RETURN_ERROR;
  161.             goto openError;
  162.         }
  163.             
  164.         if(arg[OPT_FROM])
  165.         {
  166.             name = (UBYTE **) arg[OPT_FROM];
  167.             for(; *name; name++)
  168.                 ++several;
  169.             if(several < 2)
  170.                 several = FALSE;
  171.             name = (UBYTE **) arg[OPT_FROM];
  172.             for(; *name; name++)
  173.             {
  174.                 UBYTE *dummy;
  175.                 LONG  IsWild;
  176.             
  177.                 /* Is it a pattern? */
  178.                 if(!(dummy = AllocMem(2 * strlen(*name) + 2, MEMF_PUBLIC)))
  179.                 {
  180.                     PrintFault(ERROR_NO_FREE_STORE, "Head");
  181.                     rc = RETURN_FAIL;
  182.                     break;
  183.                 }
  184.                 IsWild = ParsePattern(*name, dummy, 2 * strlen(*name) + 2);
  185.                 FreeMem(dummy, 2 * strlen(*name) + 2);
  186.                 if(IsWild == -1)
  187.                 {
  188.                     LONG err = IoErr();
  189.                     PrintFault(err, "Head");
  190.                     rc = RETURN_FAIL;
  191.                     break;
  192.                 }
  193.  
  194.                 if(!(ap = AllocMem(sizeof(struct AnchorPath) + MAXNAMELEN,
  195.                                    MEMF_PUBLIC | MEMF_CLEAR)))
  196.                 {
  197.                     PrintFault(ERROR_NO_FREE_STORE, "Head");
  198.                     rc = RETURN_FAIL;
  199.                     break;
  200.                 }
  201.  
  202.                 ap->ap_Strlen = MAXNAMELEN;
  203.  
  204.                 if(!IsWild || MatchFirst(*name, ap) == 0)
  205.                     do
  206.                     {
  207.                         if(IsWild)
  208.                         {
  209.                             several = TRUE;
  210.                             filename = ap->ap_Buf;
  211.                             if(ap->ap_Info.fib_DirEntryType > 0)
  212.                                 continue;
  213.                         }
  214.                         else
  215.                             filename = *name;
  216.                         if((rc = Head(SysBase, DOSBase, out, filename,
  217.                                       num, (BOOL) several)))
  218.                             break;
  219.                     } while(IsWild == 1 && MatchNext(ap) == 0);
  220.                 if(IsWild)
  221.                     MatchEnd(ap);
  222.                 FreeMem(ap, sizeof(struct AnchorPath) + MAXNAMELEN);
  223.             }
  224.             if(arg[OPT_TO])
  225.                 Close(out);
  226.         }
  227.         else
  228.             rc = Head(SysBase, DOSBase, out, NULL, num, (BOOL) several);
  229.  openError:
  230.         FreeArgs(args);
  231.     }
  232.     else
  233.     {
  234.         LONG err = IoErr();
  235.         PrintFault(err, "Head");
  236.         rc = RETURN_ERROR;
  237.     }
  238.                 
  239.     CloseLibrary((struct DosBase *) DOSBase);
  240.  noDOS:
  241.     return rc;
  242. }
  243.  
  244.  
  245. static LONG Head(struct Library *SysBase, struct DosLibrary *DOSBase,
  246.                  BPTR out, UBYTE *filename, LONG num, BOOL names)
  247. {
  248.     register UBYTE breakcheck = 0;
  249.     LONG  c;
  250.     ULONG count = 0;
  251.     LONG  rc = RETURN_OK;
  252.     BPTR  in = Input();
  253.     
  254.     if(filename)
  255.     {
  256.         if(names)
  257.         {
  258.             FPuts(out, "==>");
  259.             FPuts(out, filename);
  260.             FPuts(out, "<==\n");
  261.         }
  262.         if(!(in = Open(filename, MODE_OLDFILE)))
  263.         {
  264.             LONG err = IoErr();
  265.             PrintFault(err, filename);
  266.             return RETURN_ERROR;
  267.         }
  268.     }
  269.  
  270.     while((c = FGetC(in)) != -1 && count < num)
  271.     {
  272.         if(c == '\n')
  273.             ++count;
  274.         FPutC(out, c);
  275.  
  276.         if(!(breakcheck -= 8) && SetSignal(0L,0L) & SIGBREAKF_CTRL_C)
  277.         {
  278.             PrintFault(ERROR_BREAK, NULL);
  279.             rc = RETURN_WARN;
  280.             break;
  281.         }
  282.     }
  283.     if(filename)
  284.         Close(in);
  285.     return rc;
  286. }
  287.