home *** CD-ROM | disk | FTP | other *** search
/ MACD 4 / MACD4.iso / Emulatory / AROS / dos / readitem.c < prev    next >
Encoding:
C/C++ Source or Header  |  1978-03-06  |  5.3 KB  |  201 lines

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