2 Copyright © 1995-2003, The AROS Development Team. All rights reserved.
6 /* parse.c -- Here are all functions used to parse the input file */
11 #include "procedure.h"
14 /* External variables */
15 extern char buffer
[MAXARGSIZE
];
16 extern BPTR inputfile
;
17 extern InstallerPrefs preferences
;
24 * Print the sub-tree of ScriptArg *a
26 void printcode(ScriptArg
*a
, int x
)
29 /* Don't produce a SegFault if pointer is non-NULL */
30 if ((long int)a
> 1000)
32 for ( i
= 0 ; i
< x
; i
++ )
34 printf("%ld: %s , cmd=%ld, next=%ld, parent=%ld\n",(long int)a
,a
->arg
,(long int)a
->cmd
,(long int)a
->next
,(long int)a
->parent
);
35 printcode(a
->cmd
, x
+1);
36 printcode(a
->next
, x
);
43 * Read in file and generate executable tree
45 void parse_file(ScriptArg
*first
)
48 int count
, i
, j
, ready
;
55 count
= Read(inputfile
, &buffer
[0], 1);
58 PrintFault(IoErr(), INSTALLER_NAME
);
59 show_parseerror("End of File", line
);
63 if (!isspace(buffer
[0]))
67 case SEMICOLON
: /* A comment, ok - Go on with next line */
70 count
= Read(inputfile
, &buffer
[0], 1);
71 } while (buffer
[0] != LINEFEED
&& count
!= 0);
75 case LBRACK
: /* Open bracket: recurse into next level */
76 current
->cmd
= malloc(sizeof(ScriptArg
));
77 if (current
->cmd
== NULL
)
81 /* Set initial values */
82 current
->cmd
->parent
= current
;
83 current
->cmd
->arg
= NULL
;
84 current
->cmd
->cmd
= NULL
;
85 current
->cmd
->next
= NULL
;
86 current
->cmd
->intval
= 0;
87 current
->cmd
->ignore
= 0;
88 parse_file(current
->cmd
);
89 current
->next
= malloc(sizeof(ScriptArg
));
90 if (current
->next
== NULL
)
94 current
->next
->parent
= current
->parent
;
95 /* Set initial values */
96 current
= current
->next
;
104 case RBRACK
: /* All args collected return to lower level */
105 /* We have allocated one ScriptArg too much */
106 current
= current
->parent
->cmd
;
107 if (current
->next
!= NULL
)
109 while (current
->next
->next
!= NULL
)
111 current
= current
->next
;
114 current
->next
= NULL
;
118 /* This is an empty bracket */
119 show_parseerror("There is an empty bracket.", line
);
126 default: /* This is the real string */
128 if (buffer
[0] == DQUOTE
|| buffer
[0] == SQUOTE
)
130 int masquerade
= FALSE
;
133 if (masquerade
== TRUE
)
137 case 'n': /* NEWLINE */
140 case 'r': /* RETURN */
146 case SQUOTE
: /* SQUOTE */
147 buffer
[i
-1] = SQUOTE
;
149 case DQUOTE
: /* DQUOTE */
150 buffer
[i
-1] = DQUOTE
;
152 case BACKSLASH
: /* BACKSLASH */
153 buffer
[i
-1] = BACKSLASH
;
155 /* TODO: convert missing '\\' masqueraded symbols */
156 case 'h': /* H.TAB */
157 case 'v': /* V.TAB */
158 case 'b': /* BACKSPACE */
159 case 'f': /* FORMFEED */
160 case 'x': /* HEX number */
161 case 'o': /* \\ooo OCTAL number ('o' is just to remember) */
170 if (buffer
[i
] == BACKSLASH
)
176 show_parseerror("Argument length overflow!" ,line
);
180 count
= Read(inputfile
, &buffer
[i
], 1);
181 } while (masquerade
|| (buffer
[i
] != buffer
[0] && count
!= 0));
182 current
->arg
= malloc(sizeof(char)*(i
+2));
183 if (current
->arg
== NULL
)
188 strncpy (current
->arg
, buffer
, i
+2);
195 count
= Read(inputfile
, &buffer
[i
], 1);
196 } while (!isspace(buffer
[i
]) && buffer
[i
]!=LBRACK
&& buffer
[i
]!=RBRACK
&& buffer
[i
]!=SEMICOLON
&& count
!= 0 && i
< MAXARGSIZE
);
197 if (buffer
[i
] == LINEFEED
)
203 show_parseerror("Argument length overflow!", line
);
207 if (buffer
[i
] == SEMICOLON
)
211 count
= Read(inputfile
, &buffer
[i
], 1);
212 } while (buffer
[i
] != LINEFEED
&& count
!= 0);
215 if (buffer
[i
] == LBRACK
|| buffer
[i
] == RBRACK
)
217 Seek(inputfile
, -1 , OFFSET_CURRENT
);
222 case DOLLAR
: /* HEX number */
223 current
->intval
= strtol(&buffer
[1], NULL
, 16);
225 case PERCENT
: /* binary number */
226 current
->intval
= strtol(&buffer
[1], NULL
, 2);
228 default: /* number or variable */
229 if (isdigit(buffer
[0]) || ((buffer
[0] == PLUS
|| buffer
[0] == MINUS
) && isdigit(buffer
[1])))
231 current
->intval
= atol(buffer
);
235 current
->arg
= malloc(sizeof(char)*(i
+1));
236 if (current
->arg
== NULL
)
240 strncpy(current
->arg
, buffer
, i
+1);
242 if (current
== current
->parent
->cmd
&& strcasecmp(buffer
, "procedure") == 0)
244 ScriptArg
*proc
, *uproc
;
246 /* Save procedure in ProcedureList */
247 proc
= malloc(sizeof(ScriptArg
));
258 proc
->cmd
= malloc(sizeof(ScriptArg
));
259 if (proc
->cmd
== NULL
)
263 proc
->cmd
->parent
= proc
;
264 proc
->cmd
->next
= NULL
;
265 proc
->cmd
->arg
= NULL
;
266 proc
->cmd
->intval
= 0;
267 proc
->cmd
->ignore
= 0;
269 proc
->cmd
= malloc(sizeof(ScriptArg
));
270 if (proc
->cmd
== NULL
)
274 proc
->cmd
->parent
= proc
;
275 proc
->cmd
->next
= NULL
;
276 proc
->cmd
->arg
= NULL
;
277 proc
->cmd
->intval
= 0;
278 proc
->cmd
->ignore
= 0;
279 proc
->cmd
->cmd
= NULL
;
280 /* parse procedure name and args */
286 /* goto next argument */
289 count
= Read(inputfile
, &buffer
[0], 1);
290 if (buffer
[0] == LINEFEED
)
294 if (buffer
[0] == RBRACK
)
298 show_parseerror("Procedure has no body!", line
);
302 show_parseerror("Procedure has no name!", line
);
307 if (buffer
[0] == SQUOTE
|| buffer
[0] == DQUOTE
)
309 show_parseerror("Procedure has a quoted argument!", line
);
313 if (buffer
[0] == SEMICOLON
&& count
!= 0)
317 count
= Read(inputfile
, &buffer
[0], 1);
318 } while (buffer
[0] != LINEFEED
&& count
!= 0);
321 } while (isspace(buffer
[0]) && count
!= 0);
323 if (buffer
[0] != LBRACK
)
330 count
= Read(inputfile
, &buffer
[i
], 1);
331 } while (!isspace(buffer
[i
]) && buffer
[i
]!=LBRACK
&& buffer
[i
]!=RBRACK
&& buffer
[i
]!=SEMICOLON
&& count
!= 0 && i
< MAXARGSIZE
);
334 show_parseerror("Argument length overflow!", line
);
338 if (buffer
[i
] == LINEFEED
)
342 if (buffer
[i
] == LBRACK
|| buffer
[i
] == RBRACK
|| buffer
[i
] == SEMICOLON
)
344 Seek(inputfile
, -1 , OFFSET_CURRENT
);
348 mclip
= realloc(mclip
, sizeof(char *) * j
);
353 mclip
[j
-1] = strdup(buffer
);
354 if (mclip
[j
-1] == NULL
)
361 /* Exit if procedure has no name or name is string/digit or bracket follows */
364 show_parseerror("Argument to procedure is a command!\n", line
);
368 /* Next string is body-command */
373 parse_file(proc
->cmd
);
379 count
= Read(inputfile
, &buffer
[0], 1);
380 if (buffer
[0] == LINEFEED
)
384 } while (isspace(buffer
[0]) && count
!= 0);
385 if (buffer
[0] == SEMICOLON
)
389 count
= Read(inputfile
, &buffer
[0], 1);
390 } while (buffer
[0] != LINEFEED
&& count
!= 0);
393 else if (buffer
[0] == LBRACK
)
395 proc
->next
= malloc(sizeof(ScriptArg
));
396 if (proc
->next
== NULL
)
400 proc
->next
->parent
= proc
->parent
;
401 proc
->next
->next
= NULL
;
402 proc
->next
->arg
= NULL
;
403 proc
->next
->intval
= 0;
404 proc
->next
->ignore
= 0;
406 proc
->cmd
= malloc(sizeof(ScriptArg
));
407 if (proc
->cmd
== NULL
)
411 proc
->cmd
->parent
= proc
;
412 proc
->cmd
->next
= NULL
;
413 proc
->cmd
->arg
= NULL
;
414 proc
->cmd
->intval
= 0;
415 proc
->cmd
->ignore
= 0;
416 proc
->cmd
->cmd
= NULL
;
417 parse_file(proc
->cmd
);
419 else if (buffer
[0] == RBRACK
)
425 show_parseerror("Procedure has rubbish in its body!", line
);
430 current
->next
= malloc(sizeof(ScriptArg
));
431 if (current
->next
== NULL
)
435 current
->next
->parent
= current
->parent
;
436 current
= current
->next
;
437 current
->arg
= mclip
[0];
439 current
->next
= NULL
;
440 current
->intval
= set_procedure(mclip
, j
, uproc
);
449 if (current
->arg
== current
->parent
->cmd
->arg
&& strcasecmp(buffer
, "welcome") == 0)
451 preferences
.welcome
= TRUE
;
456 current
->next
= malloc(sizeof(ScriptArg
));
457 if (current
->next
== NULL
)
461 current
->next
->parent
= current
->parent
;
462 current
= current
->next
;
463 /* Set initial values */
466 current
->next
= NULL
;
474 if (buffer
[0] == LINEFEED
)
481 PrintFault(IoErr(), INSTALLER_NAME
);
482 show_parseerror("End of File", line
);