2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
8 #include <proto/exec.h>
9 #include <dos/rdargs.h>
10 #include <dos/dosasl.h>
11 #include <dos/dosextens.h>
12 #include "dos_intern.h"
14 /*****************************************************************************
17 #include <proto/dos.h>
19 AROS_LH3(LONG
, ReadItem
,
22 AROS_LHA(STRPTR
, buffer
, D1
),
23 AROS_LHA(LONG
, maxchars
, D2
),
24 AROS_LHA(struct CSource
*, input
, D3
),
27 struct DosLibrary
*, DOSBase
, 135, Dos
)
30 Read an item from a given character source. Items are words
31 or quoted strings separated by whitespace or '=' just like on
32 the commandline. The separator is unread and the output string
33 is terminated by a NUL character.
36 buffer - Buffer to be filled.
37 maxchars - Size of the buffer. Must be at least 1 (for the NUL
39 input - A ready to use CSource structure or NULL which means
40 "read from the input stream".
43 One of ITEM_UNQUOTED - Normal word read.
44 ITEM_QUOTED - Quoted string read.
45 ITEM_NOTHING - End of line found. Nothing read.
46 ITEM_EQUAL - '=' read. Buffer is empty.
47 ITEM_ERROR - An error happened.
50 This function handles conversion of '**', '*"', etc. inside quotes.
52 This function has well known bugs, and should be avoided
58 1. Forgets to unread a separator character (equal sign, whitespace or
60 2. Tries to unread an end-of-line, which actually causes unreading the
61 last read character of CSource if supplied. Even if it's not a
62 separator, but belongs to the last read item.
63 3. IoErr() is never modified by this function.
65 As AOS programs that use ReadItem() depend on this broken behaviour,
68 4. If maxchars == 0, buffer[0] is set to NUL anyway.
74 *****************************************************************************/
80 * As mentioned above, this code has some intentional (but not obvious) bugs.
81 * They must not be fixed.
82 * If you change something here, be sure that the code passes unit tests
83 * in test/dos/readitem. Those unit tests are verified to pass on AmigaOS 3.1.
86 /* Macro to get a character from the input source */
90 if(input->CS_CurChr>=input->CS_Length) \
93 c=input->CS_Buffer[input->CS_CurChr++]; \
99 /* Macro to push the character back */
100 #define UNGET() {if(input!=NULL) input->CS_CurChr--; else UnGetC(Input(),-1);}
114 /* Skip leading whitespace characters */
118 } while (c
==' '||c
=='\t');
120 if(!c
||c
=='\n'||c
==EOF
||c
==';')
128 /* Found '='. Return it. */
132 /* Quoted item found. Convert Contents. */
142 /* Convert ** to *, *" to ", *n to \n and *e to 0x1b. */
146 /* Check for premature end of line. */
147 if(!c
||c
=='\n'||c
==EOF
)
152 }else if(c
=='n'||c
=='N')
154 else if(c
=='e'||c
=='E')
156 }else if(!c
||c
=='\n'||c
==EOF
)
163 /* " ends the item. */
171 /* Unquoted item. Store first character. */
179 /* Read up to the next terminator. */
189 /* Check for terminator */
190 if(!c
||c
==' '||c
=='\t'||c
=='\n'||c
=='='||c
==EOF
)
192 /* To be compatible with AOS, we need
193 * to *not* UNGET() here if we see a space
196 * Yes, it's broken, but so are any programs
197 * that actually used ReadItem(), and relied
200 if (c
!= '=' && c
!= ' ' && c
!= '\t')
203 return ITEM_UNQUOTED
;