home *** CD-ROM | disk | FTP | other *** search
/ Aminet 18 / aminetcdnumber181997.iso / Aminet / misc / emu / AROSdev.lha / AROS / rom / dos / readitem.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-27  |  5.5 KB  |  209 lines

  1. /*
  2.     (C) 1995-96 AROS - The Amiga Replacement OS
  3.     $Id: readitem.c,v 1.6 1997/01/27 00:36:28 ldp Exp $
  4.     $Log: readitem.c,v $
  5.     Revision 1.6  1997/01/27 00:36:28  ldp
  6.     Polish
  7.  
  8.     Revision 1.5  1996/12/09 13:53:39  aros
  9.     Added empty templates for all missing functions
  10.  
  11.     Moved #include's into first column
  12.  
  13.     Revision 1.4  1996/10/24 15:50:35  aros
  14.     Use the official AROS macros over the __AROS versions.
  15.  
  16.     Revision 1.3  1996/08/13 13:52:50  digulla
  17.     Replaced <dos/dosextens.h> by "dos_intern.h" or added "dos_intern.h"
  18.     Replaced AROS_LA by AROS_LHA
  19.  
  20.     Revision 1.2  1996/08/01 17:40:56  digulla
  21.     Added standard header for all files
  22.  
  23.     Desc:
  24.     Lang: english
  25. */
  26. #include <proto/exec.h>
  27. #include <dos/rdargs.h>
  28. #include <dos/dosasl.h>
  29. #include <dos/dosextens.h>
  30. #include "dos_intern.h"
  31.  
  32. /*****************************************************************************
  33.  
  34.     NAME */
  35. #include <proto/dos.h>
  36.  
  37.     AROS_LH3(LONG, ReadItem,
  38.  
  39. /*  SYNOPSIS */
  40.     AROS_LHA(STRPTR,           buffer,   D1),
  41.     AROS_LHA(LONG,             maxchars, D2),
  42.     AROS_LHA(struct CSource *, input,    D3),
  43.  
  44. /*  LOCATION */
  45.     struct DosLibrary *, DOSBase, 135, Dos)
  46.  
  47. /*  FUNCTION
  48.     Read an item from a given character source. Items are words
  49.     or quoted strings seperated by whitespace or '=' just like on
  50.     the commandline. The seperator is unread and the read string
  51.     is terminated by a NUL character.
  52.  
  53.     INPUTS
  54.     buffer   - Buffer to be filled.
  55.     maxchars - Size of the buffer. Must be at least 1 (for the terminator).
  56.     input    - A ready to use CSource structure or NULL which means
  57.            "read from the input stream".
  58.  
  59.     RESULT
  60.     One of ITEM_UNQUOTED - Normal word read.
  61.            ITEM_QUOTED   - Quoted string read.
  62.            ITEM_NOTHING  - End of line found. Nothing read.
  63.            ITEM_EQUAL    - '=' read. Buffer is empty.
  64.            ITEM_ERROR    - An error happened. IoErr() gives additional
  65.                            information in that case.
  66.  
  67.     NOTES
  68.     This function handles conversion of '**', '*"', etc inside quotes.
  69.  
  70.     EXAMPLE
  71.  
  72.     BUGS
  73.  
  74.     SEE ALSO
  75.  
  76.     INTERNALS
  77.  
  78.     HISTORY
  79.     29-10-95    digulla automatically created from
  80.                 dos_lib.fd and clib/dos_protos.h
  81.  
  82. *****************************************************************************/
  83. {
  84.     AROS_LIBFUNC_INIT
  85.     AROS_LIBBASE_EXT_DECL(struct DosLibrary *,DOSBase)
  86.  
  87. /* Macro to get a character from the input source */
  88. #define GET(c)                     \
  89. if(input!=NULL)                    \
  90. {                        \
  91.     if(input->CS_CurChr>=input->CS_Length)    \
  92.         c=EOF;                    \
  93.     else                    \
  94.         c=input->CS_Buffer[input->CS_CurChr++];    \
  95. }else                        \
  96. {                           \
  97.     c=FGetC(Input());                \
  98.     if(c==EOF&&*result)                \
  99.         return ITEM_ERROR;            \
  100. }
  101.  
  102. /* Macro to push the character back */
  103. #define UNGET() if(input!=NULL) input->CS_CurChr--; else UnGetC(Input(),-1);
  104.  
  105.     STRPTR b=buffer;
  106.     LONG c;
  107.     LONG *result=&((struct Process *)FindTask(NULL))->pr_Result2;
  108.     
  109.     /* Skip leading whitespace characters */
  110.     do
  111.     {
  112.         GET(c);
  113.     }while(c==' '||c=='\t'||c=='\n');
  114.  
  115.     if(!c||c=='\n'||c==EOF)
  116.     {
  117.         /*
  118.             End of line found. Note that unlike the Amiga DOS original
  119.             this funtion doesn't know about ';' comments. Comments are
  120.             the shell's job, IMO. I don't need them here.
  121.         */
  122.         if(c!=EOF)
  123.             UNGET();
  124.         *b=0;
  125.         return ITEM_NOTHING;
  126.     }else if(c=='=')
  127.     {
  128.         /* Found '='. Return it. */
  129.         *b=0;
  130.         return ITEM_EQUAL;
  131.     }else if(c=='\"')
  132.         /* Quoted item found. Convert Contents. */
  133.         for(;;)
  134.         {
  135.             if(!maxchars)
  136.             {
  137.                 *buffer=0;
  138.                 *result=ERROR_BUFFER_OVERFLOW;
  139.                 return ITEM_ERROR;
  140.             }
  141.             maxchars--;
  142.             GET(c);
  143.             /* Convert ** to *, *" to ", *n to \n and *e to 0x1b. */
  144.             if(c=='*')
  145.             {
  146.                 GET(c);
  147.                 /* Check for premature end of line. */
  148.                 if(!c||c=='\n'||c==EOF)
  149.                 {
  150.                     if(c!=EOF)
  151.                         UNGET();
  152.                     *buffer=0;
  153.                     *result=ERROR_UNMATCHED_QUOTES;
  154.                     return ITEM_ERROR;
  155.                 }else if(c=='n'||c=='N')
  156.                     c='\n';
  157.                 else if(c=='e'||c=='E')
  158.                     c=0x1b;
  159.             }else if(!c||c=='\n'||c==EOF)
  160.             {
  161.                 if(c!=EOF)
  162.                     UNGET();
  163.                 *buffer=0;
  164.                 *result=ERROR_UNMATCHED_QUOTES;
  165.                 return ITEM_ERROR;
  166.             }else if(c=='\"')
  167.             {
  168.                 /* " ends the item. */
  169.                 *b=0;
  170.                 return ITEM_QUOTED;
  171.             }
  172.             *b++=c;
  173.         }
  174.     else
  175.     {
  176.         /* Unquoted item. Store first character. */
  177.         if(!maxchars)
  178.         {
  179.             *buffer=0;
  180.             *result=ERROR_BUFFER_OVERFLOW;
  181.             return ITEM_ERROR;
  182.         }
  183.         maxchars--;
  184.         *b++=c;
  185.         /* Read upto the next terminator. */
  186.         for(;;)
  187.         {
  188.             if(!maxchars)
  189.             {
  190.                 *buffer=0;
  191.                 *result=ERROR_BUFFER_OVERFLOW;
  192.                 return ITEM_ERROR;
  193.             }
  194.             maxchars--;
  195.             GET(c);
  196.             /* Check for terminator */
  197.             if(!c||c==' '||c=='\t'||c=='\n'||c=='='||c==EOF)
  198.             {
  199.                 if(c!=EOF)
  200.                     UNGET();
  201.                 *b=0;
  202.                 return ITEM_UNQUOTED;
  203.             }
  204.             *b++=c;
  205.         }
  206.     }
  207.     AROS_LIBFUNC_EXIT
  208. } /* ReadItem */
  209.