Skip to content

Commit ca7c025

Browse files
committed
FIX: Interpreter too eagerly consuming command-line arguments & arguments containing whitespace
resolves: Oldes/Rebol-issues#2227 resolves: Oldes/Rebol-issues#1890
1 parent 7f13439 commit ca7c025

File tree

4 files changed

+42
-45
lines changed

4 files changed

+42
-45
lines changed

src/core/b-init.c

+23-5
Original file line numberDiff line numberDiff line change
@@ -819,12 +819,13 @@ static void Set_Option_File(REBCNT field, REBYTE* src, REBOOL dir )
819819
***********************************************************************/
820820
{
821821
REBVAL *val;
822+
REBCHR *arg;
823+
REBVAL *new;
822824
REBSER *ser;
823825
REBCHR *data;
824826
REBCNT n;
825827

826828
#ifdef RAW_MAIN_ARGS
827-
REBVAL *new;
828829
// make system/options/flags block even when not used...
829830
val = Get_System(SYS_OPTIONS, OPTIONS_FLAGS);
830831
Set_Block(val, Make_Block(3));
@@ -834,7 +835,7 @@ static void Set_Option_File(REBCNT field, REBYTE* src, REBOOL dir )
834835
// convert raw argument strings to block of strings...
835836
ser = Make_Block(3);
836837
for (n = 1; n < rargs->argc ; n++) {
837-
REBCHR *arg = rargs->argv[n];
838+
arg = rargs->argv[n];
838839
if (arg == 0) continue; // shell bug
839840
new = Append_Value(ser);
840841
Set_String(new, Copy_OS_Str(arg, (REBINT)LEN_STR(arg)));
@@ -843,7 +844,7 @@ static void Set_Option_File(REBCNT field, REBYTE* src, REBOOL dir )
843844
val = Get_System(SYS_OPTIONS, OPTIONS_ARGS);
844845
Set_Block(val, ser);
845846
#else
846-
847+
// collect flags...
847848
ser = Make_Block(3);
848849
n = 2; // skip first flag (ROF_EXT)
849850
val = Get_System(SYS_CATALOG, CAT_BOOT_FLAGS);
@@ -874,9 +875,26 @@ static void Set_Option_File(REBCNT field, REBYTE* src, REBOOL dir )
874875
n = Set_Option_Word(rargs->boot, OPTIONS_BOOT_LEVEL);
875876
if (n >= SYM_BASE && n <= SYM_MODS)
876877
PG_Boot_Level = n - SYM_BASE; // 0 - 3
878+
879+
// store args in a block
880+
ser = Make_Block(3);
881+
if (rargs->args) {
882+
// if used --args, store this value as a first one
883+
new = Append_Value(ser);
884+
Set_String(new, Copy_OS_Str(rargs->args, (REBINT)LEN_STR(rargs->args)));
885+
}
886+
// the rest of args, if there are any...
887+
for (n = 0; n < rargs->argc; n++) {
888+
arg = rargs->argv[n];
889+
if (arg == 0) continue; // shell bug
890+
new = Append_Value(ser);
891+
Set_String(new, Copy_OS_Str(arg, (REBINT)LEN_STR(arg)));
892+
//if(arg[0]=='-') VAL_SET_LINE(new);
893+
}
894+
val = Get_System(SYS_OPTIONS, OPTIONS_ARGS);
895+
Set_Block(val, ser);
877896

878-
Set_Option_String(rargs->args, OPTIONS_ARGS);
879-
Set_Option_String(rargs->do_arg, OPTIONS_DO_ARG);
897+
// other option values...
880898
Set_Option_String(rargs->debug, OPTIONS_DEBUG);
881899
Set_Option_String(rargs->version, OPTIONS_VERSION);
882900
Set_Option_String(rargs->import, OPTIONS_IMPORT);

src/include/reb-args.h

+3-5
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
typedef struct rebol_args {
3232
REBCNT options;
3333
REBCHR *script;
34-
REBCHR *args;
3534
REBCHR *do_arg;
3635
REBCHR *version;
3736
REBCHR *debug;
@@ -40,10 +39,9 @@ typedef struct rebol_args {
4039
REBCHR *boot;
4140
REBCHR *exe_path;
4241
REBCHR *current_dir;
43-
#ifdef RAW_MAIN_ARGS
44-
REBCNT argc;
45-
REBCHR **argv;
46-
#endif
42+
REBCHR *args; // value for the --args option
43+
REBCNT argc; // unprocessed argument count
44+
REBCHR **argv; // unprocessed arguments
4745
} REBARGS;
4846

4947
// REBOL arg option flags:

src/mezz/sys-start.reb

+3-1
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,9 @@ start: func [
204204
header: first code
205205
parent: none
206206
path: what-dir
207-
args: script-args
207+
; if there was used --args option, pass to script only this value
208+
; and ignore other optional arguments
209+
args: either system/options/flags/args [to block! first script-args][script-args]
208210
]
209211
either 'module = select first code 'type [
210212
code: reduce [first+ code code]

src/os/host-args.c

+13-34
Original file line numberDiff line numberDiff line change
@@ -215,15 +215,9 @@ const struct arg_chr arg_chars2[] = {
215215
OS_Get_Current_Dir(&rargs->current_dir);
216216

217217
#else
218-
int arg_buf_size=128;
219218

220219
REBCHR *arg;
221-
REBCHR *args = NULL; // holds trailing args
222-
int flag;
223-
int i;
224-
int len;
225-
int size;
226-
REBCHR *tmp;
220+
int flag, i;
227221

228222
CLEARS(rargs);
229223

@@ -241,6 +235,10 @@ const struct arg_chr arg_chars2[] = {
241235
if (arg == 0) continue; // shell bug
242236
if (*arg == '-') {
243237
if (arg[1] == '-') {
238+
if (arg[2] == 0) {
239+
// -- stops options parsing for the interpreter
240+
break;
241+
}
244242
// --option words
245243
flag = find_option_word(arg+2);
246244
if (flag & RO_EXT) {
@@ -280,35 +278,16 @@ const struct arg_chr arg_chars2[] = {
280278
}
281279
else {
282280
// script filename
283-
if (!rargs->script)
284-
rargs->script = arg;
285-
else {
286-
if (!args) {
287-
args = MAKE_STR(arg_buf_size);
288-
if (!args) return;
289-
args[0] = 0;
290-
}
291-
len = (int)LEN_STR(arg) + (int)LEN_STR(args) + 2;
292-
size = arg_buf_size;
293-
while (size < len) size *= 2;
294-
if (size > arg_buf_size) {
295-
tmp = args;
296-
args = MAKE_STR(size);
297-
if (!args) return;
298-
memcpy(args, tmp, arg_buf_size);
299-
arg_buf_size = size;
300-
FREE_MEM(tmp);
301-
}
302-
len = arg_buf_size - (int)LEN_STR(args) - 2; // space remaining
303-
JOIN_STR(args, arg, len);
304-
JOIN_STR(args, TXT(" "), 1);
305-
}
281+
rargs->script = arg;
282+
// after having processed a command-line argument as scriptname,
283+
// all remaining arguments are passed as-is to the script (via system/options/args)
284+
break;
306285
}
307286
}
308-
309-
if (args) {
310-
args[LEN_STR(args)-1] = 0; // remove trailing space
311-
Get_Ext_Arg(RO_ARGS, rargs, args);
287+
// if there are still unprocessed args, pass them as a block (converted later in b-init.c)
288+
if (argc > i++) {
289+
rargs->argc = argc - i;
290+
rargs->argv = argv + i;
312291
}
313292
#endif
314293
}

0 commit comments

Comments
 (0)