2 Copyright © 1995-2011, 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. IoErr() gives additional
48 information in that case.
51 This function handles conversion of '**', '*"', etc inside quotes.
53 This function has well known bugs, and should be avoided
59 1. Forgets to unread a separator character (equal sign, whitespace or
61 2. Tries to unread an end-of-line, which actually causes unreading the
62 last read character of CSource is supplied. Even if it's not a separator,
63 but belongs to last read item.
64 3. IoErr() is never modified by this function.
66 As AOS programs that use ReadItem() depend on this broken behaviour,
69 4. If maxchars == 0, buff[0] is set to 0 anyway.
75 *****************************************************************************/
81 * As mentioned above, this code has some intentional (but not obvious) bugs.
82 * They must not be fixed.
83 * If you change something here, be sure that the code passes unit tests
84 * in test/dos/readitem. Those unit tests are verified to pass on AmigaOS 3.1.
87 /* Macro to get a character from the input source */
91 if(input->CS_CurChr>=input->CS_Length) \
94 c=input->CS_Buffer[input->CS_CurChr++]; \
100 /* Macro to push the character back */
101 #define UNGET() {if(input!=NULL) input->CS_CurChr--; else UnGetC(Input(),-1);}
115 /* Skip leading whitespace characters */
119 } while (c
==' '||c
=='\t');
121 if(!c
||c
=='\n'||c
==EOF
||c
==';')
129 /* Found '='. Return it. */
133 /* Quoted item found. Convert Contents. */
143 /* Convert ** to *, *" to ", *n to \n and *e to 0x1b. */
147 /* Check for premature end of line. */
148 if(!c
||c
=='\n'||c
==EOF
)
153 }else if(c
=='n'||c
=='N')
155 else if(c
=='e'||c
=='E')
157 }else if(!c
||c
=='\n'||c
==EOF
)
164 /* " ends the item. */
172 /* Unquoted item. Store first character. */
180 /* Read up to the next terminator. */
190 /* Check for terminator */
191 if(!c
||c
==' '||c
=='\t'||c
=='\n'||c
=='='||c
==EOF
)
193 /* To be compatible with AOS, we need
194 * to *not* UNGET() here if we see a space
197 * Yes, it's broken, but so are any programs
198 * that actually used ReadItem(), and relied
201 if (c
!= '=' && c
!= ' ' && c
!= '\t')
204 return ITEM_UNQUOTED
;