revert between 56095 -> 55830 in arch
[AROS.git] / arch / m68k-all / dos / bcpl_readargs.c
blob89695b6ed800dc248b73bb7ccc6d16f082399743
1 /*
2 Copyright © 2010, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: BCPL support
6 Lang: english
7 */
8 #define DEBUG 0
9 #include <aros/debug.h>
10 #include <aros/asmcall.h>
12 #include <exec/memory.h>
13 #include <proto/exec.h>
14 #include <dos/rdargs.h>
15 #include <dos/dosextens.h>
17 /*****************************************************************************
19 NAME */
20 #include <proto/dos.h>
22 AROS_UFH4(ULONG, BCPL_ReadArgs,
23 /* SYNOPSIS */
24 AROS_UFHA(BSTR, btemplate, D1),
25 AROS_UFHA(BPTR, bvec, D2),
26 AROS_UFHA(ULONG, upb, D3),
27 AROS_UFHA(struct DosLibrary *, DOSBase, A6))
29 /* LOCATION
30 BCPL Vector offset 0x138
32 FUNCTION
33 Parses the commandline, a given string or Input() and fills
34 an argument array according to the options template given.
35 The array must be initialized to the wanted defaults before
36 each call to ReadArgs().
37 ReadArgs() tries to parse the commandline and continues
38 on the input channel if it just consists of a single '?',
39 prompting the user for input.
41 INPUTS
42 template - Template string. The template string is given as
43 a number of options separated by ',' and modified
44 by '/' modifiers, e.g. 'NAME,WIDTH/N,HEIGHT/N'
45 means get a name string and two numbers (width and
46 height). The possible modifiers are:
47 /S Option is a switch. It may be either set or
48 left out.
49 /T Option is a boolean value. Requires an argument
50 which may be "ON", "YES" (setting the respective
51 argument to 1), "OFF" or "NO" (setting the
52 respective argument to 0).
53 /N Option is a number. Strings are not allowed.
54 If the option is optional, a pointer to the
55 actual number is returned. This is how you know
56 if it was really given. The number is always of type
57 LONG.
58 /A Argument is required. If it is left out ReadArgs()
59 fails.
60 /K The keyword must be given when filling the option.
61 Normally it's skipped.
62 /M Multiple strings or, when used in combination with /N,
63 numbers. The result is returned as an array of pointers
64 to strings or LONGs, and is terminated with NULL. /M
65 eats all strings that don't fit into any other option.
66 If there are unfilled /A arguments after parsing they
67 steal strings from /M. This makes it possible to, for
68 example, write a Copy command template like
69 'FROM/A/M,TO/A'. There may be only one /M option in a
70 template.
71 /F Eats the rest of the line even if there are option
72 keywords in it.
73 array - Array to be filled with the result values. The array must
74 be intialized to the default values before calling
75 ReadArgs().
76 array_wl - Maximum size of input
78 RESULT
79 Number of words used in argv
81 SEE ALSO
82 Input()
84 *****************************************************************************/
86 AROS_USERFUNC_INIT
88 STRPTR template;
89 IPTR *vec = BADDR(bvec);
90 struct RDArgs *rd;
91 BSTR bstr;
92 CONST_STRPTR cp;
93 int arg, args, seen_key, seen_enough, svec;
94 #define RA_FLAG(x) ((x)&0x1f)
96 template = AllocVec(AROS_BSTR_strlen(btemplate)+1,MEMF_ANY);
97 if (template == NULL) {
98 SetIoErr(ERROR_NO_FREE_STORE);
99 return 0;
102 memcpy(template, AROS_BSTR_ADDR(btemplate), AROS_BSTR_strlen(btemplate));
103 template[AROS_BSTR_strlen(btemplate)]=0;
105 D(bug("-- Template \"%s\"\n", template));
107 /* Count args in the template */
108 for (args = 1, cp = template; *cp; cp++) {
109 if (*cp == ',')
110 args++;
113 /* BCPL readargs appers to want the vector to be zeroed */
114 memset(vec, 0, upb * sizeof(IPTR));
116 rd = ReadArgs(template, vec, NULL);
117 if (rd == NULL) {
118 FreeVec(template);
119 return 0;
122 svec = args;
123 seen_enough = 0;
124 for (arg = 0, seen_key = 0, cp = template; ; cp++) {
125 int len, left;
127 if (*cp == ',' || (cp - template) >= AROS_BSTR_strlen(btemplate)) {
128 if (!seen_enough && vec[arg] != 0) {
129 /* Ok, it's probably a string. Convert it to BCPL */
130 len = strlen((STRPTR)vec[arg]);
131 left = (upb - svec)*sizeof(IPTR);
132 if (AROS_BSTR_MEMSIZE4LEN(len) > left) {
133 SetIoErr(ERROR_NO_FREE_STORE);
134 FreeArgs(rd);
135 FreeVec(template);
136 return 0;
139 bstr = MKBADDR(&vec[svec]);
140 D(bug("-- Convert arg %d (%p) \"%s\" to BCPL 0x%x at %p\n", arg, (APTR)vec[arg], (APTR)vec[arg], bstr, &vec[svec]));
141 memcpy(AROS_BSTR_ADDR(bstr), (APTR)vec[arg], len);
142 AROS_BSTR_setstrlen(bstr, len);
143 vec[arg] = bstr;
144 svec += AROS_ALIGN(AROS_BSTR_MEMSIZE4LEN(len))/sizeof(IPTR);
146 if (*cp != ',')
147 break;
148 arg++;
149 seen_key = 0;
150 continue;
153 if (!seen_key && *cp == '/') {
154 seen_key = 1;
155 seen_enough = 0;
156 continue;
159 if (!seen_key)
160 continue;
162 if (seen_enough)
163 continue;
165 if (RA_FLAG(*cp) == RA_FLAG('N')) {
166 seen_enough=1;
167 continue;
169 if (RA_FLAG(*cp) == RA_FLAG('S')) {
170 seen_enough=1;
171 continue;
173 if (RA_FLAG(*cp) == RA_FLAG('T')) {
174 seen_enough=1;
175 continue;
179 FreeVec(template);
180 FreeArgs(rd);
182 SetIoErr(0);
183 return svec;
185 AROS_USERFUNC_EXIT