home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 15 / AACD15.ISO / AACD / Utilities / Extract / Extract.c next >
Encoding:
C/C++ Source or Header  |  1995-12-04  |  7.4 KB  |  330 lines

  1. /************************************************************************
  2. *******************************  EXTRACT  *******************************
  3. *************************************************************************
  4.  
  5.                             -------------------
  6.                              Copyright © 1995
  7.                               Nick Christie.
  8.                             39 St Georges Drive
  9.                             Bransgore BH23 8EZ
  10.                               Great Britain.
  11.                             All Rights Reserved
  12.                             -------------------
  13.  
  14. Tabsize:    4
  15.  
  16. Version:    $VER: Extract 1.00 (3.12.95)
  17.  
  18. Author:        Nick Christie
  19.  
  20. E-Mail:        nick.christie@oucs.ox.ac.uk
  21.  
  22. Address:    39 St Georges Drive
  23.             Bransgore BH23 8EZ
  24.             Great Britain.
  25.  
  26. Keywords:    Programming, Shell, CLI, Text, Batch.
  27.  
  28. Purpose:    To find and print to stdout part of a text file, specified
  29.             using either line or byte offset and length.
  30.  
  31. Requires:    Kickstart 2.04+ (V37+).
  32.  
  33. Distribution: Freeware. Source in C included.
  34.  
  35. Compiler:    SAS/C V6.56
  36.  
  37. To Make:    smake -f Extract.smake
  38.  
  39.             Make sure that the compiler library picks up the amiga lib
  40.             stdio stuff, not the ANSI C versions.
  41.  
  42.             You will need to edit the smakefile if you do not put
  43.             TinyStart.o in LIB:. Note the use of registerized
  44.             parameters and the GST file 'include:all.gst'.
  45.  
  46. Usage:        Extract FILE/A OFFSET/N LENGTH/N BYTES/S
  47.  
  48. Where:        FILE
  49.                 is the file to extract a section from.
  50.             OFFSET
  51.                 is the 0-based line or byte offset to start at. If the
  52.                 offset is past the end of the file, nothing is printed.
  53.             LENGTH
  54.                 is the number of lines or bytes to print. If the length
  55.                 extends beyond the end of the file, printing stops at EOF.
  56.             BYTES
  57.                 is a switch that indicates the offset and length
  58.                 are in bytes rather than lines.
  59.  
  60. Returns:    0  if all went hokey-dokey and the section was printed.
  61.             10 if the file was not found
  62.             20 if there was some other error, eg. not enough memory.
  63.  
  64. Notes:        If an error occurs, an error message will be printed to
  65.             stdout. These will always start with "Error:", except for
  66.             the usage message.
  67.  
  68. *************************************************************************/
  69.  
  70. /************************************************************************
  71. ******************************  INCLUDES  *******************************
  72. ************************************************************************/
  73.  
  74. #include <stdio.h>
  75. #include <stdlib.h>
  76. #include <string.h>
  77. #include <exec/memory.h>
  78. #include <dos/dos.h>
  79. #include <dos/stdio.h>
  80. #include <dos/dostags.h>
  81. #include <proto/exec.h>
  82. #include <proto/dos.h>
  83.  
  84. /************************************************************************
  85. *****************************  DEFINITIONS  *****************************
  86. *************************************************************************/
  87.  
  88. /*
  89.  * Program name, version, etc
  90.  */
  91.  
  92. #define PROGNAME            "Extract"
  93. #define PROGVER                "1.0"
  94. #define PROGVERNUM            1
  95. #define PROGREVNUM            0
  96. #define PROGDATE            __AMIGADATE__
  97.  
  98. /*
  99.  * Command line parsing template
  100.  */
  101.  
  102. #define SHELLTEMPLATE        "FILE/A,OFFSET/A/N,LENGTH/A/N,BYTES/S"
  103.  
  104. /*
  105.  * Buffer sizes
  106.  */
  107.  
  108. #define LINEBUFSIZE            1024
  109. #define BYTEBUFSIZE            8192
  110.  
  111. /*
  112.  * Indices into arg array
  113.  */
  114.  
  115. enum InitArgs {
  116.         ARG_FILE=0,
  117.         ARG_OFF,
  118.         ARG_LEN,
  119.         ARG_BYTES,
  120.         ARG_TOTAL
  121. };
  122.  
  123. /************************************************************************
  124. *****************************  REFERENCES  ******************************
  125. ************************************************************************/
  126.  
  127. /*
  128.  * Data from startup module
  129.  */
  130.  
  131. extern struct Library        *SysBase;
  132.  
  133. /************************************************************************
  134. *****************************  PROTOTYPES  ******************************
  135. *************************************************************************/
  136.  
  137. ULONG main(char *cmdline,ULONG cmdlen);
  138.  
  139. ULONG ExtractBytes(BPTR fh,ULONG off,ULONG len);
  140. ULONG ExtractLines(BPTR fh,ULONG off,ULONG len);
  141.  
  142. /************************************************************************
  143. ********************************  DATA  *********************************
  144. ************************************************************************/
  145.  
  146. /*
  147.  * Embedded version string
  148.  */
  149.  
  150. char VersionStr[] = "\0$VER: " PROGNAME " " PROGVER " " PROGDATE "\0";
  151.  
  152. /************************************************************************
  153. *******************************  MAIN()  ********************************
  154. *************************************************************************
  155. * Program entry point, from TinyStart.o startup module using register
  156. * parameters: cmdline ptr in a0, cmdline length in d0. Length is 0 if
  157. * from WB. Returns ULONG DOS result code.
  158. *
  159. *************************************************************************/
  160.  
  161. ULONG main(char *cmdline,ULONG cmdlen)
  162. {
  163. struct RDArgs    *rda;
  164. BPTR            fh;
  165. LONG            args[ARG_TOTAL];
  166. ULONG            rc,off,len;
  167.  
  168. rc = RETURN_FAIL;
  169.  
  170. if (cmdlen && (SysBase->lib_Version >= 37))
  171.     {
  172.     memset(args,0,sizeof(args));
  173.  
  174.     if (rda = ReadArgs(SHELLTEMPLATE,args,NULL))
  175.         {
  176.         rc = RETURN_ERROR;
  177.  
  178.         if (fh = Open((char *)args[ARG_FILE],MODE_OLDFILE))
  179.             {
  180.             off = *((ULONG *)args[ARG_OFF]);
  181.             len = *((ULONG *)args[ARG_LEN]);
  182.  
  183.             if (args[ARG_BYTES])
  184.                 rc = ExtractBytes(fh,off,len);
  185.             else
  186.                 rc = ExtractLines(fh,off,len);
  187.  
  188.             Close(fh);
  189.             }
  190.         else
  191.             PrintFault(IoErr(),"Error");
  192.  
  193.         FreeArgs(rda);
  194.         }
  195.     else
  196.         PrintFault(IoErr(),"Error");
  197.     }
  198.  
  199. return(rc);
  200. }
  201.  
  202. /************************************************************************
  203. ***************************  EXTRACTBYTES()  ****************************
  204. *************************************************************************
  205. * Print len bytes to stdout from file whose handle is supplied, starting
  206. * at byte offset off. Returns RETURN_OK if all went well, RETURN_FAIL
  207. * on error.
  208. *
  209. *************************************************************************/
  210.  
  211. ULONG ExtractBytes(BPTR fh,ULONG off,ULONG len)
  212. {
  213. char    *buf;
  214. BPTR    outfh;
  215. ULONG    rc,get,got;
  216. LONG    err;
  217.  
  218. rc = RETURN_FAIL;
  219. outfh = Output();
  220.  
  221. Seek(fh,off,OFFSET_BEGINNING);
  222.  
  223. if (IoErr())
  224.     PrintFault(IoErr(),"Error");
  225. else
  226.     {
  227.     if (buf = AllocMem(BYTEBUFSIZE,MEMF_PUBLIC|MEMF_ANY))
  228.         {
  229.         get = BYTEBUFSIZE;
  230.         err = 0;
  231.  
  232.         while(len && !err)
  233.             {
  234.             if (get > len)
  235.                 get = len;
  236.             len -= get;
  237.             got = Read(fh,buf,get);
  238.             if (got != -1)
  239.                 {
  240.                 if (got)
  241.                     {
  242.                     if (Write(outfh,buf,got) == -1)
  243.                         err = IoErr();
  244.                     }
  245.                 else
  246.                     len = 0;
  247.                 }
  248.             else
  249.                 err = IoErr();
  250.             }
  251.  
  252.         if (err)
  253.             PrintFault(err,"Error");
  254.         else
  255.             rc = RETURN_OK;
  256.  
  257.         FreeMem(buf,BYTEBUFSIZE);
  258.         }
  259.     else
  260.         PrintFault(ERROR_NO_FREE_STORE,"Error");
  261.     }
  262.  
  263. return(rc);
  264. }
  265.  
  266. /************************************************************************
  267. ***************************  EXTRACTLINES()  ****************************
  268. *************************************************************************
  269. * Print len lines to stdout from file whose handle is supplied, starting
  270. * at line number off. Returns RETURN_OK if all went well, RETURN_FAIL
  271. * on error.
  272. *
  273. *************************************************************************/
  274.  
  275. ULONG ExtractLines(BPTR fh,ULONG off,ULONG len)
  276. {
  277. char    *buf;
  278. BPTR    outfh;
  279. LONG    err;
  280. ULONG    rc;
  281.  
  282. rc = RETURN_FAIL;
  283. outfh = Output();
  284.  
  285. if (buf = AllocMem(LINEBUFSIZE,MEMF_PUBLIC|MEMF_ANY))
  286.     {
  287.     err = 0;
  288.     rc = RETURN_OK;
  289.  
  290.     while(off && !err)
  291.         {
  292.         if (FGets(fh,buf,LINEBUFSIZE-1))
  293.             off--;
  294.         else
  295.             {
  296.             off = 0;
  297.             err = IoErr();
  298.             }
  299.         }
  300.  
  301.     while(len && !err)
  302.         {
  303.         if (FGets(fh,buf,LINEBUFSIZE-1))
  304.             {
  305.             if (FPuts(outfh,buf))
  306.                 err = IoErr();
  307.             len--;
  308.             }
  309.         else
  310.             {
  311.             len = 0;
  312.             err = IoErr();
  313.             }
  314.         }
  315.  
  316.     if (err)
  317.         {
  318.         rc = RETURN_FAIL;
  319.         PrintFault(err,"Error");
  320.         }
  321.  
  322.     FreeMem(buf,LINEBUFSIZE);
  323.     }
  324. else
  325.     PrintFault(ERROR_NO_FREE_STORE,"Error");
  326.  
  327. return(rc);
  328. }
  329.  
  330.