1 /****************************************************************************/
2 /*                                                                          */
3 /*  Module:         jamexec.c                                               */
4 /*                                                                          */
5 /*                  Copyright (C) Altera Corporation 1997                   */
6 /*                                                                          */
7 /*  Description:    Contains the main entry point urj_jam_execute(), and    */
8 /*                  other functions to implement the main execution loop.   */
9 /*                  This loop repeatedly calls urj_jam_get_statement() and  */
10 /*                  urj_jam_execute_statement() to process statements in    */
11 /*                  the JAM source file.                                    */
12 /*                                                                          */
13 /*  Revisions:      1.1 added support for VECTOR CAPTURE and VECTOR COMPARE */
14 /*                  statements                                              */
15 /*                  added support for dynamic memory allocation             */
16 /*                  1.2 fixed STATE statement to accept a space-separated   */
17 /*                  list of states as well as a comma-separated list        */
18 /*                                                                          */
19 /****************************************************************************/
20 
21 #include <stdint.h>
22 #include "jamexprt.h"
23 #include "jamdefs.h"
24 #include "jamexec.h"
25 #include "jamutil.h"
26 #include "jamexp.h"
27 #include "jamsym.h"
28 #include "jamstack.h"
29 #include "jamheap.h"
30 #include "jamarray.h"
31 #include "jamjtag.h"
32 #include "jamcomp.h"
33 
34 /****************************************************************************/
35 /*                                                                          */
36 /*  Global variables                                                        */
37 /*                                                                          */
38 /****************************************************************************/
39 
40 /* pointer to memory buffer for variable, symbol and stack storage */
41 char *urj_jam_workspace = NULL;
42 
43 /* size of available memory buffer */
44 int32_t urj_jam_workspace_size = 0L;
45 
46 /* pointer to Jam program text */
47 char *urj_jam_program = NULL;
48 
49 /* size of program buffer */
50 int32_t urj_jam_program_size = 0L;
51 
52 /* current position in input stream */
53 int32_t urj_jam_current_file_position = 0L;
54 
55 /* position in input stream of the beginning of the current statement */
56 int32_t urj_jam_current_statement_position = 0L;
57 
58 /* position of the beginning of the next statement (the one after the */
59 /* current statement, but not necessarily the next one to be executed) */
60 int32_t urj_jam_next_statement_position = 0L;
61 
62 /* name of desired action (Jam 2.0 only) */
63 char *urj_jam_action = NULL;
64 
65 /* pointer to initialization list */
66 char **urj_jam_init_list = NULL;
67 
68 /* buffer for constant literal boolean array data */
69 #define JAMC_MAX_LITERAL_ARRAYS 4
70 int32_t urj_jam_literal_array_buffer[JAMC_MAX_LITERAL_ARRAYS];
71 
72 /* buffer for constant literal ACA array data */
73 int32_t *urj_jam_literal_aca_buffer[JAMC_MAX_LITERAL_ARRAYS];
74 
75 /* number of vector signals */
76 int urj_jam_vector_signal_count = 0;
77 
78 /* version of Jam language used:  0 = unknown */
79 int urj_jam_version = 0;
80 
81 /* phase of Jam execution */
82 JAME_PHASE_TYPE urj_jam_phase = JAM_UNKNOWN_PHASE;
83 
84 /* current procedure or data block */
85 JAMS_SYMBOL_RECORD *urj_jam_current_block = NULL;
86 
87 /* this global flag indicates that we are processing the items in */
88 /* the "uses" list for a procedure, executing the data blocks if */
89 /* they have not yet been initialized, but not calling any procedures */
90 BOOL urj_jam_checking_uses_list = false;
91 
92 /* function prototypes for forward reference */
93 int urj_jam_get_statement (char *statement_buffer, char *label_buffer);
94 JAME_INSTRUCTION urj_jam_get_instruction (char *statement);
95 int urj_jam_skip_instruction_name (const char *statement_buffer);
96 int urj_jam_find_keyword (const char *buffer, char *keyword);
97 int urj_jam_get_array_subrange (JAMS_SYMBOL_RECORD *symbol_record,
98                             char *statement_buffer, int32_t *start_index,
99                             int32_t *stop_index);
100 int urj_jam_convert_literal_binary (char *statement_buffer,
101                                 int32_t **output_buffer, int32_t *length,
102                                 int arg);
103 int urj_jam_convert_literal_array (char *statement_buffer,
104                                int32_t **output_buffer, int32_t *length,
105                                int arg);
106 int urj_jam_convert_literal_aca (char *statement_buffer, int32_t **output_buffer,
107                              int32_t *length, int arg);
108 int urj_jam_get_array_argument (char *statement_buffer,
109                             JAMS_SYMBOL_RECORD **symbol_record,
110                             int32_t **literal_array_data,
111                             int32_t *start_index, int32_t *stop_index,
112                             int arg);
113 int urj_jam_find_argument (char *statement_buffer, int *begin, int *end,
114                        int *delimiter);
115 int urj_jam_process_uses_item (char *block_name);
116 int urj_jam_process_uses_list (char *uses_list);
117 int urj_jam_call_procedure (char *procedure_name, BOOL *done, int *exit_code);
118 int urj_jam_call_procedure_from_action (char *procedure_name, BOOL *done,
119                                     int *exit_code);
120 int urj_jam_call_procedure_from_procedure (char *procedure_name, BOOL *done,
121                                        int *exit_code);
122 int urj_jam_process_action (char *statement_buffer, BOOL *done, int *exit_code);
123 int urj_jam_process_boolean (char *statement_buffer);
124 int urj_jam_process_call_or_goto (char *statement_buffer, BOOL call_statement,
125                               BOOL *done, int *exit_code);
126 int urj_jam_process_data (char *statement_buffer);
127 int urj_jam_process_drscan_compare (char *statement_buffer, int32_t count_value,
128                                 int32_t *in_data, int32_t in_index);
129 int urj_jam_process_drscan_capture (char *statement_buffer, int32_t count_value,
130                                 int32_t *in_data, int32_t in_index);
131 int urj_jam_process_drscan (char *statement_buffer);
132 int urj_jam_process_drstop (char *statement_buffer);
133 int urj_jam_process_enddata (char *statement_buffer);
134 int urj_jam_process_exit (char *statement_buffer, BOOL *done, int *exit_code);
135 int urj_jam_process_export (char *statement_buffer);
136 int urj_jam_process_for (char *statement_buffer);
137 int urj_jam_process_frequency (char *statement_buffer);
138 int urj_jam_process_if (char *statement_buffer, BOOL *reuse_statement_buffer);
139 int urj_jam_process_integer (char *statement_buffer);
140 int urj_jam_process_irscan_compare (char *statement_buffer, int32_t count_value,
141                                 int32_t *in_data, int32_t in_index);
142 int urj_jam_process_irscan_capture (char *statement_buffer, int32_t count_value,
143                                 int32_t *in_data, int32_t in_index);
144 int urj_jam_process_irscan (char *statement_buffer);
145 int urj_jam_process_irstop (char *statement_buffer);
146 int urj_jam_copy_array_subrange (int32_t *source_heap_data,
147                              int32_t source_subrange_begin,
148                              int32_t source_subrange_end,
149                              int32_t *dest_heap_data,
150                              int32_t dest_subrange_begin,
151                              int32_t dest_subrange_end);
152 BOOL urj_jam_check_assignment (char *statement_buffer);
153 int urj_jam_process_assignment (char *statement_buffer, BOOL let);
154 int urj_jam_process_next (char *statement_buffer);
155 int urj_jam_process_padding (char *statement_buffer);
156 int urj_jam_process_pop (char *statement_buffer);
157 int urj_jam_process_pre_post (JAME_INSTRUCTION instruction_code,
158                           char *statement_buffer);
159 int urj_jam_process_print (char *statement_buffer);
160 int urj_jam_process_procedure (char *statement_buffer);
161 int urj_jam_process_push (char *statement_buffer);
162 int urj_jam_process_return (char *statement_buffer, BOOL endproc);
163 int urj_jam_find_state_argument (char *statement_buffer, int *begin, int *end,
164                              int *delimiter);
165 int urj_jam_process_state (char *statement_buffer);
166 int urj_jam_process_trst (char *statement_buffer);
167 int urj_jam_process_vector_capture (char *statement_buffer, int signal_count,
168                                 int32_t *dir_vector, int32_t *data_vector);
169 int urj_jam_process_vector_compare (char *statement_buffer, int signal_count,
170                                 int32_t *dir_vector, int32_t *data_vector);
171 int urj_jam_process_vector (char *statement_buffer);
172 int urj_jam_process_vmap (char *statement_buffer);
173 int urj_jam_process_wait_cycles (char *statement_buffer,
174                              JAME_JTAG_STATE wait_state);
175 int urj_jam_process_wait_microseconds (char *statement_buffer,
176                                    JAME_JTAG_STATE wait_state);
177 int urj_jam_process_wait (char *statement_buffer);
178 void urj_jam_free_literal_aca_buffers (void);
179 int urj_jam_execute_statement (char *statement_buffer, BOOL *done,
180                            BOOL *reuse_statement_buffer, int *exit_code);
181 int32_t urj_jam_get_line_of_position (int32_t position);
182 int urj_jam_execute (char *program, int32_t program_size, char *workspace,
183                  int32_t workspace_size, char *action, char **init_list,
184                  int reset_jtag, int32_t *error_line, int *exit_code,
185                  int *format_version);
186 
187 /****************************************************************************/
188 /*                                                                          */
189 
190 JAM_RETURN_TYPE
urj_jam_get_statement(char * statement_buffer,char * label_buffer)191 urj_jam_get_statement (char *statement_buffer, char *label_buffer)
192 /*                                                                          */
193 /*  Description:    This function reads a full statement from the input     */
194 /*                  stream, preprocesses it to remove comments, and stores  */
195 /*                  it in a buffer.  If the statement is an array           */
196 /*                  declaration the initialization data is not stored in    */
197 /*                  the buffer but must be read from the input stream when  */
198 /*                  the array is used.                                      */
199 /*                                                                          */
200 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
201 /*                                                                          */
202 /****************************************************************************/
203 {
204     int index = 0;
205     int label_index = 0;
206     int ch = 0;
207     int last_ch = 0;
208     BOOL comment = false;
209     BOOL quoted_string = false;
210     BOOL boolean_array_data = false;
211     BOOL literal_aca_array = false;
212     BOOL label_found = false;
213     BOOL done = false;
214     int32_t position = urj_jam_current_file_position;
215     int32_t first_char_position = -1L;
216     int32_t semicolon_position = -1L;
217     int32_t left_quote_position = -1L;
218     JAM_RETURN_TYPE status = JAMC_SUCCESS;
219 
220     label_buffer[0] = JAMC_NULL_CHAR;
221     statement_buffer[0] = JAMC_NULL_CHAR;
222 
223     while (!done)
224     {
225         last_ch = ch;
226         ch = urj_jam_getc ();
227 
228         if ((!comment) && (!quoted_string))
229         {
230             if (ch == JAMC_COMMENT_CHAR)
231             {
232                 /* beginning of comment */
233                 comment = true;
234             }
235             else if (ch == JAMC_QUOTE_CHAR)
236             {
237                 /* beginning of quoted string */
238                 quoted_string = true;
239                 left_quote_position = position;
240             }
241             else if (ch == JAMC_COLON_CHAR)
242             {
243                 /* statement contains a label */
244                 if (label_found)
245                 {
246                     /* multiple labels found */
247                     status = JAMC_SYNTAX_ERROR;
248                     done = true;
249                 }
250                 else if (index <= JAMC_MAX_NAME_LENGTH)
251                 {
252                     /* copy label into label_buffer */
253                     for (label_index = 0; label_index < index; label_index++)
254                     {
255                         label_buffer[label_index] =
256                             statement_buffer[label_index];
257                     }
258                     label_buffer[index] = JAMC_NULL_CHAR;
259                     label_found = true;
260 
261                     /* delete label from statement_buffer */
262                     index = 0;
263                     statement_buffer[0] = JAMC_NULL_CHAR;
264                     first_char_position = -1L;
265                     ch = JAMC_SPACE_CHAR;
266                 }
267                 else
268                 {
269                     /* label name was too int32_t */
270                     status = JAMC_ILLEGAL_SYMBOL;
271                     done = true;
272                 }
273             }
274             else if ((ch == JAMC_TAB_CHAR) ||
275                      (ch == JAMC_NEWLINE_CHAR) || (ch == JAMC_RETURN_CHAR))
276             {
277                 /* convert tab, CR, LF to space character */
278                 ch = JAMC_SPACE_CHAR;
279             }
280         }
281 
282         /* save character in statement_buffer */
283         if ((!comment) && (index < JAMC_MAX_STATEMENT_LENGTH) &&
284             ((first_char_position != -1L) || (ch != JAMC_SPACE_CHAR)) &&
285             (quoted_string ||
286              (ch != JAMC_SPACE_CHAR) || (last_ch != JAMC_SPACE_CHAR)))
287         {
288             /* save the character */
289             /* convert to upper case except quotes and boolean arrays */
290             if (quoted_string || boolean_array_data || literal_aca_array)
291             {
292                 statement_buffer[index] = (char) ch;
293             }
294             else
295             {
296                 statement_buffer[index] = (char)
297                     (((ch >= 'a') && (ch <= 'z')) ? (ch - ('a' - 'A')) : ch);
298             }
299             ++index;
300             if (first_char_position == -1L)
301                 first_char_position = position;
302 
303             /*
304              *      Whenever we see a right bracket character, check if the
305              *      statement is a Boolean array declaration statement.
306              */
307             if ((!boolean_array_data) && (ch == JAMC_RBRACKET_CHAR)
308                 && (statement_buffer[0] == 'B'))
309             {
310                 if (strncmp (statement_buffer, "BOOLEAN", 7) == 0)
311                 {
312                     boolean_array_data = true;
313                 }
314             }
315 
316             /*
317              *      Check for literal ACA array assignment
318              */
319             if ((!quoted_string) && (!boolean_array_data) &&
320                 (!literal_aca_array) && (ch == JAMC_AT_CHAR))
321             {
322                 /* this is the beginning of a literal ACA array */
323                 literal_aca_array = true;
324             }
325 
326             if (literal_aca_array &&
327                 (!isalnum ((char) ch)) &&
328                 (ch != JAMC_AT_CHAR) &&
329                 (ch != JAMC_UNDERSCORE_CHAR) && (ch != JAMC_SPACE_CHAR))
330             {
331                 /* this is the end of the literal ACA array */
332                 literal_aca_array = false;
333             }
334         }
335 
336         if ((!comment) && (!quoted_string) && (ch == JAMC_SEMICOLON_CHAR))
337         {
338             /* end of statement */
339             done = true;
340             semicolon_position = position;
341         }
342 
343         if (ch == EOF)
344         {
345             /* end of file */
346             done = true;
347             status = JAMC_UNEXPECTED_END;
348         }
349 
350         if (comment &&
351             ((ch == JAMC_NEWLINE_CHAR) || (ch == JAMC_RETURN_CHAR)))
352         {
353             /* end of comment */
354             comment = false;
355         }
356         else if (quoted_string && (ch == JAMC_QUOTE_CHAR) &&
357                  (position > left_quote_position))
358         {
359             /* end of quoted string */
360             quoted_string = false;
361         }
362 
363         ++position;             /* position of next character to be read */
364     }
365 
366     if (index < JAMC_MAX_STATEMENT_LENGTH)
367     {
368         statement_buffer[index] = JAMC_NULL_CHAR;
369     }
370     else
371     {
372         statement_buffer[JAMC_MAX_STATEMENT_LENGTH] = JAMC_NULL_CHAR;
373     }
374 
375     urj_jam_current_file_position = position;
376 
377     if (first_char_position != -1L)
378     {
379         urj_jam_current_statement_position = first_char_position;
380     }
381 
382     if (semicolon_position != -1L)
383     {
384         urj_jam_next_statement_position = semicolon_position + 1;
385     }
386 
387     return status;
388 }
389 
390 struct JAMS_INSTR_MAP
391 {
392     JAME_INSTRUCTION instruction;
393     char string[JAMC_MAX_INSTR_LENGTH + 1];
394 } static const jam_instruction_table[] =
395 {
396     {JAM_ACTION_INSTR, "ACTION"},
397     {JAM_BOOLEAN_INSTR, "BOOLEAN"},
398     {JAM_CALL_INSTR, "CALL"},
399     {JAM_CRC_INSTR, "CRC"},
400     {JAM_DATA_INSTR, "DATA"},
401     {JAM_DRSCAN_INSTR, "DRSCAN"},
402     {JAM_DRSTOP_INSTR, "DRSTOP"},
403     {JAM_ENDDATA_INSTR, "ENDDATA"},
404     {JAM_ENDPROC_INSTR, "ENDPROC"},
405     {JAM_EXIT_INSTR, "EXIT"},
406     {JAM_EXPORT_INSTR, "EXPORT"},
407     {JAM_FOR_INSTR, "FOR"},
408     {JAM_FREQUENCY_INSTR, "FREQUENCY"},
409     {JAM_GOTO_INSTR, "GOTO"},
410     {JAM_IF_INSTR, "IF"},
411     {JAM_INTEGER_INSTR, "INTEGER"},
412     {JAM_IRSCAN_INSTR, "IRSCAN"},
413     {JAM_IRSTOP_INSTR, "IRSTOP"},
414     {JAM_LET_INSTR, "LET"},
415     {JAM_NEXT_INSTR, "NEXT"},
416     {JAM_NOTE_INSTR, "NOTE"},
417     {JAM_PADDING_INSTR, "PADDING"},
418     {JAM_POP_INSTR, "POP"},
419     {JAM_POSTDR_INSTR, "POSTDR"},
420     {JAM_POSTIR_INSTR, "POSTIR"},
421     {JAM_PREDR_INSTR, "PREDR"},
422     {JAM_PREIR_INSTR, "PREIR"},
423     {JAM_PRINT_INSTR, "PRINT"},
424     {JAM_PROCEDURE_INSTR, "PROCEDURE"},
425     {JAM_PUSH_INSTR, "PUSH"},
426     {JAM_REM_INSTR, "REM"},
427     {JAM_RETURN_INSTR, "RETURN"},
428     {JAM_STATE_INSTR, "STATE"},
429     {JAM_TRST_INSTR, "TRST"},
430     {JAM_VECTOR_INSTR, "VECTOR"},
431     {JAM_VMAP_INSTR, "VMAP"},
432     {JAM_WAIT_INSTR, "WAIT"}
433 };
434 
435 /****************************************************************************/
436 /*                                                                          */
437 
438 JAME_INSTRUCTION
urj_jam_get_instruction(char * statement)439 urj_jam_get_instruction (char *statement)
440 /*                                                                          */
441 /*  Description:    This function extracts the instruction name from the    */
442 /*                  statement buffer and looks up the instruction code.     */
443 /*                                                                          */
444 /*  Returns:        instruction code                                        */
445 /*                                                                          */
446 /****************************************************************************/
447 {
448     int index = 0;
449     int instr_index = 0;
450     int length = 0;
451     BOOL done = false;
452     JAME_INSTRUCTION instruction = JAM_ILLEGAL_INSTR;
453     char instr_name[JAMC_MAX_INSTR_LENGTH + 1];
454 
455     /*
456      *      Extract instruction name and convert to upper case
457      */
458     for (index = 0; (!done) && (index < JAMC_MAX_INSTR_LENGTH); index++)
459     {
460         /* copy characters until non-alphabetic character */
461         if ((statement[index] >= 'A') && (statement[index] <= 'Z'))
462         {
463             instr_name[index] = statement[index];
464         }
465         else if ((statement[index] >= 'a') && (statement[index] <= 'z'))
466         {
467             /* convert to upper case */
468             instr_name[index] = (char) ((statement[index] - 'a') + 'A');
469         }
470         else
471         {
472             /* end of instruction name */
473             instr_name[index] = JAMC_NULL_CHAR;
474             length = index;
475             done = true;
476         }
477     }
478 
479     /*
480      *      Search for instruction name in instruction table
481      */
482     if (done && (length > 0))
483     {
484         done = false;
485 
486         for (index = 0; (!done) && (index < ARRAY_SIZE(jam_instruction_table)); index++)
487         {
488             done = true;
489 
490             for (instr_index = 0; done && (instr_index < length);
491                  instr_index++)
492             {
493                 if (instr_name[instr_index] !=
494                     jam_instruction_table[index].string[instr_index])
495                 {
496                     done = false;
497                 }
498             }
499 
500             if (done && (jam_instruction_table[index].string[length] != '\0'))
501             {
502                 done = false;
503             }
504 
505             if (done)
506             {
507                 instruction = jam_instruction_table[index].instruction;
508             }
509         }
510     }
511 
512     return instruction;
513 }
514 
515 /****************************************************************************/
516 /*                                                                          */
517 
518 int
urj_jam_skip_instruction_name(const char * statement_buffer)519 urj_jam_skip_instruction_name (const char *statement_buffer)
520 /*                                                                          */
521 /*  Description:    This function skips over the first "word" in the        */
522 /*                  statement buffer, which is assumed to be the name of    */
523 /*                  the instruction, and returns the index of the next      */
524 /*                  non-white-space character in the buffer.                */
525 /*                                                                          */
526 /*  Returns:        index of statement text after instruction name          */
527 /*                                                                          */
528 /****************************************************************************/
529 {
530     int index = 0;
531 
532     while ((isspace (statement_buffer[index])) &&
533            (index < JAMC_MAX_STATEMENT_LENGTH))
534     {
535         ++index;                /* skip over white space */
536     }
537 
538     while ((jam_is_name_char (statement_buffer[index])) &&
539            (index < JAMC_MAX_STATEMENT_LENGTH))
540     {
541         ++index;                /* skip over instruction name */
542     }
543 
544     while ((isspace (statement_buffer[index])) &&
545            (index < JAMC_MAX_STATEMENT_LENGTH))
546     {
547         ++index;                /* skip over white space */
548     }
549 
550     return index;
551 }
552 
553 /****************************************************************************/
554 /*                                                                          */
555 
556 int
urj_jam_find_keyword(const char * buffer,char * keyword)557 urj_jam_find_keyword (const char *buffer, char *keyword)
558 /*                                                                          */
559 /*  Description:    This function searches in the statement buffer for the  */
560 /*                  specified keyword.                                      */
561 /*                                                                          */
562 /*  Returns:        index of keyword in buffer, or -1 if keyword not found  */
563 /*                                                                          */
564 /****************************************************************************/
565 {
566     BOOL found = false;
567     int index = 0;
568     int buffer_length = strlen (buffer);
569     int keyword_length = strlen (keyword);
570 
571     /* look at beginning of string */
572     if ((buffer[0] == keyword[0]) &&
573         (strncmp (buffer, keyword, keyword_length) == 0) &&
574         (!jam_is_name_char (buffer[keyword_length])))
575     {
576         found = true;
577     }
578 
579     /* look inside string */
580     while ((!found) && (index + keyword_length <= buffer_length))
581     {
582         if ((buffer[index + 1] == keyword[0]) &&
583             (!jam_is_name_char (buffer[index])) &&
584             (strncmp (&buffer[index + 1], keyword, keyword_length) == 0)
585             && (!jam_is_name_char (buffer[index + keyword_length + 1])))
586         {
587             found = true;
588         }
589 
590         ++index;
591     }
592 
593     return found ? index : -1;
594 }
595 
596 /****************************************************************************/
597 /*                                                                          */
598 
urj_jam_get_array_subrange(JAMS_SYMBOL_RECORD * symbol_record,char * statement_buffer,int32_t * start_index,int32_t * stop_index)599 JAM_RETURN_TYPE urj_jam_get_array_subrange
600     (JAMS_SYMBOL_RECORD *symbol_record,
601      char *statement_buffer, int32_t *start_index, int32_t *stop_index)
602 /*                                                                          */
603 /*  Description:    Gets start_index and stop_index of an array subrange    */
604 /*                  specification of the form <start_index>..<stop_index>   */
605 /*                                                                          */
606 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
607 /*                                                                          */
608 /****************************************************************************/
609 {
610     int index = 0;
611     int expr_begin = 0;
612     int expr_end = 0;
613     char save_ch = 0;
614     BOOL found_elipsis = false;
615     BOOL found = false;
616     JAM_RETURN_TYPE status = JAMC_SUCCESS;
617     JAME_EXPRESSION_TYPE expr_type = JAM_ILLEGAL_EXPR_TYPE;
618 
619     while ((statement_buffer[index] != JAMC_NULL_CHAR) && !found_elipsis)
620     {
621         if ((statement_buffer[index] == JAMC_PERIOD_CHAR) &&
622             (statement_buffer[index + 1] == JAMC_PERIOD_CHAR))
623         {
624             expr_end = index;
625             found_elipsis = true;
626         }
627         ++index;
628     }
629 
630     if (found_elipsis && (expr_end > expr_begin))
631     {
632         save_ch = statement_buffer[expr_end];
633         statement_buffer[expr_end] = JAMC_NULL_CHAR;
634         status =
635             urj_jam_evaluate_expression (&statement_buffer[expr_begin],
636                                      start_index, &expr_type);
637         statement_buffer[expr_end] = save_ch;
638 
639         /*
640          *      Check for integer expression
641          */
642         if ((status == JAMC_SUCCESS) &&
643             (expr_type != JAM_INTEGER_EXPR) &&
644             (expr_type != JAM_INT_OR_BOOL_EXPR))
645         {
646             status = JAMC_TYPE_MISMATCH;
647         }
648     }
649     else
650     {
651         status = JAMC_SYNTAX_ERROR;
652     }
653 
654     if (status == JAMC_SUCCESS)
655     {
656         expr_begin = expr_end + 2;
657 
658         status =
659             urj_jam_evaluate_expression (&statement_buffer[expr_begin],
660                                      stop_index, &expr_type);
661 
662         if ((status == JAMC_SUCCESS) &&
663             (expr_type != JAM_INTEGER_EXPR) &&
664             (expr_type != JAM_INT_OR_BOOL_EXPR))
665         {
666             status = JAMC_TYPE_MISMATCH;
667         }
668         else
669         {
670             found = true;
671         }
672     }
673 
674     if ((status == JAMC_SUCCESS) && (!found))
675     {
676         status = JAMC_SYNTAX_ERROR;
677     }
678 
679     if ((urj_jam_version == 2) && (!found_elipsis) && (symbol_record != NULL))
680     {
681         /* if there is nothing between the brackets, select the entire array */
682         index = 0;
683 
684         while (isspace (statement_buffer[index]))
685             ++index;
686 
687         if (statement_buffer[index] == JAMC_NULL_CHAR)
688         {
689             JAMS_HEAP_RECORD *heap_record =
690                 (JAMS_HEAP_RECORD *) symbol_record->value;
691 
692             if (heap_record == NULL)
693             {
694                 status = JAMC_INTERNAL_ERROR;
695             }
696             else
697             {
698                 *start_index = heap_record->dimension - 1;
699                 *stop_index = 0;
700                 status = JAMC_SUCCESS;
701             }
702         }
703     }
704 
705     if ((status == JAMC_SUCCESS) && (urj_jam_version == 2))
706     {
707         /* for Jam 2.0, swap the start and stop indices */
708         int32_t temp = *start_index;
709         *start_index = *stop_index;
710         *stop_index = temp;
711     }
712 
713     return status;
714 }
715 
716 /****************************************************************************/
717 /*                                                                          */
718 
urj_jam_convert_literal_binary(char * statement_buffer,int32_t ** output_buffer,int32_t * length,int arg)719 JAM_RETURN_TYPE urj_jam_convert_literal_binary
720     (char *statement_buffer,
721      int32_t **output_buffer, int32_t *length, int arg)
722 /*                                                                          */
723 /*  Description:    converts BINARY string in statement buffer into binary  */
724 /*                  values.  Stores binary result back into the buffer,     */
725 /*                  overwriting the input text.                             */
726 /*                                                                          */
727 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
728 /*                                                                          */
729 /****************************************************************************/
730 {
731     int in_index = 0;
732     int out_index = 0;
733     int rev_index = 0;
734     int i = 0;
735     int j = 0;
736     char ch = 0;
737     int data = 0;
738     int32_t *long_ptr = NULL;
739     JAM_RETURN_TYPE status = JAMC_SUCCESS;
740 
741     while ((status == JAMC_SUCCESS) &&
742            ((ch = statement_buffer[in_index]) != '\0'))
743     {
744         if ((ch == '0') || (ch == '1'))
745         {
746             data = (int) (ch - '0');
747         }
748         else
749         {
750             status = JAMC_SYNTAX_ERROR;
751         }
752 
753         if (status == JAMC_SUCCESS)
754         {
755             if ((in_index & 7) == 0)
756             {
757                 statement_buffer[out_index] = 0;
758             }
759 
760             if (data)
761             {
762                 statement_buffer[out_index] |= (1 << (in_index & 7));
763             }
764 
765             if ((in_index & 7) == 7)
766             {
767                 ++out_index;
768             }
769         }
770 
771         ++in_index;
772     }
773 
774     if (status == JAMC_SUCCESS)
775     {
776         *length = (int32_t) in_index;
777 
778         /* reverse the order of binary data */
779         rev_index = in_index / 2;
780         while (rev_index > 0)
781         {
782             data = (statement_buffer[(rev_index - 1) >> 3] &
783                     (1 << ((rev_index - 1) & 7)));
784 
785             if (statement_buffer[(in_index - rev_index) >> 3] &
786                 (1 << ((in_index - rev_index) & 7)))
787             {
788                 statement_buffer[(rev_index - 1) >> 3] |=
789                     (1 << ((rev_index - 1) & 7));
790             }
791             else
792             {
793                 statement_buffer[(rev_index - 1) >> 3] &=
794                     ~(1 << ((rev_index - 1) & 7));
795             }
796 
797             if (data)
798             {
799                 statement_buffer[(in_index - rev_index) >> 3] |=
800                     (1 << ((in_index - rev_index) & 7));
801             }
802             else
803             {
804                 statement_buffer[(in_index - rev_index) >> 3] &=
805                     ~(1 << ((in_index - rev_index) & 7));
806             }
807 
808             --rev_index;
809         }
810 
811         out_index = (in_index + 7) / 8; /* number of bytes */
812         rev_index = (out_index + 3) / 4;        /* number of longs */
813 
814         if (rev_index > 1)
815         {
816             long_ptr =
817                 (int32_t *) (((int32_t) statement_buffer) & 0xfffffffcL);
818         }
819         else if (arg < JAMC_MAX_LITERAL_ARRAYS)
820         {
821             long_ptr = &urj_jam_literal_array_buffer[arg];
822         }
823         else
824         {
825             status = JAMC_INTERNAL_ERROR;
826         }
827     }
828 
829     if (status == JAMC_SUCCESS)
830     {
831         for (i = 0; i < rev_index; ++i)
832         {
833             j = i * 4;
834             long_ptr[i] = ((((int32_t) statement_buffer[j + 3] << 24L) &
835                             0xff000000L) | (((int32_t) statement_buffer[j + 2]
836                                              << 16L) & 0x00ff0000L) |
837                            (((int32_t) statement_buffer[j + 1] << 8L) &
838                             0x0000ff00L) | (((int32_t) statement_buffer[j]) &
839                                             0x000000ffL));
840         }
841 
842         if (output_buffer != NULL)
843             *output_buffer = long_ptr;
844     }
845 
846     return status;
847 }
848 
849 /****************************************************************************/
850 /*                                                                          */
851 
urj_jam_convert_literal_array(char * statement_buffer,int32_t ** output_buffer,int32_t * length,int arg)852 JAM_RETURN_TYPE urj_jam_convert_literal_array
853     (char *statement_buffer,
854      int32_t **output_buffer, int32_t *length, int arg)
855 /*                                                                          */
856 /*  Description:    converts HEX string in statement buffer into binary     */
857 /*                  values.  Stores binary result back into the buffer,     */
858 /*                  overwriting the input text.                             */
859 /*                                                                          */
860 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
861 /*                                                                          */
862 /****************************************************************************/
863 {
864     int in_index = 0;
865     int out_index = 0;
866     int rev_index = 0;
867     int i = 0;
868     int j = 0;
869     char ch = 0;
870     int data = 0;
871     int32_t *long_ptr = NULL;
872     JAM_RETURN_TYPE status = JAMC_SUCCESS;
873 
874     while ((status == JAMC_SUCCESS) &&
875            ((ch = statement_buffer[in_index]) != '\0'))
876     {
877         if ((ch >= 'A') && (ch <= 'F'))
878         {
879             data = (int) (ch + 10 - 'A');
880         }
881         else if ((ch >= 'a') && (ch <= 'f'))
882         {
883             data = (int) (ch + 10 - 'a');
884         }
885         else if ((ch >= '0') && (ch <= '9'))
886         {
887             data = (int) (ch - '0');
888         }
889         else
890         {
891             status = JAMC_SYNTAX_ERROR;
892         }
893 
894         if (status == JAMC_SUCCESS)
895         {
896             if (in_index & 1)
897             {
898                 /* odd nibble is lower nibble */
899                 data |= (statement_buffer[out_index] & 0xf0);
900                 statement_buffer[out_index] = (char) data;
901                 ++out_index;
902             }
903             else
904             {
905                 /* even nibble is upper nibble */
906                 statement_buffer[out_index] = (char) (data << 4);
907             }
908         }
909 
910         ++in_index;
911     }
912 
913     if (status == JAMC_SUCCESS)
914     {
915         *length = (int32_t) in_index *4L;
916 
917         if (in_index & 1)
918         {
919             /* odd number of nibbles - do a nibble-shift */
920             out_index = in_index / 2;
921             while (out_index > 0)
922             {
923                 statement_buffer[out_index] = (char)
924                     (((statement_buffer[out_index - 1] & 0x0f) << 4) |
925                      ((statement_buffer[out_index] & 0xf0) >> 4));
926                 --out_index;
927             }
928             statement_buffer[0] = (char) ((statement_buffer[0] & 0xf0) >> 4);
929             ++in_index;
930         }
931 
932         /* reverse the order of binary data */
933         out_index = in_index / 2;       /* number of bytes */
934         rev_index = out_index / 2;
935         while (rev_index > 0)
936         {
937             ch = statement_buffer[rev_index - 1];
938             statement_buffer[rev_index - 1] =
939                 statement_buffer[out_index - rev_index];
940             statement_buffer[out_index - rev_index] = ch;
941             --rev_index;
942         }
943 
944         out_index = (in_index + 1) / 2; /* number of bytes */
945         rev_index = (out_index + 3) / 4;        /* number of longs */
946 
947         if (rev_index > 1)
948         {
949             long_ptr =
950                 (int32_t *) (((int32_t) statement_buffer) & 0xfffffffcL);
951         }
952         else if (arg < JAMC_MAX_LITERAL_ARRAYS)
953         {
954             long_ptr = &urj_jam_literal_array_buffer[arg];
955         }
956         else
957         {
958             status = JAMC_INTERNAL_ERROR;
959         }
960     }
961 
962     if (status == JAMC_SUCCESS)
963     {
964         for (i = 0; i < rev_index; ++i)
965         {
966             j = i * 4;
967             long_ptr[i] = ((((int32_t) statement_buffer[j + 3] << 24L) &
968                             0xff000000L) | (((int32_t) statement_buffer[j + 2]
969                                              << 16L) & 0x00ff0000L) |
970                            (((int32_t) statement_buffer[j + 1] << 8L) &
971                             0x0000ff00L) | (((int32_t) statement_buffer[j]) &
972                                             0x000000ffL));
973         }
974 
975         if (output_buffer != NULL)
976             *output_buffer = long_ptr;
977     }
978 
979     return status;
980 }
981 
982 /****************************************************************************/
983 /*                                                                          */
984 
urj_jam_convert_literal_aca(char * statement_buffer,int32_t ** output_buffer,int32_t * length,int arg)985 JAM_RETURN_TYPE urj_jam_convert_literal_aca
986     (char *statement_buffer,
987      int32_t **output_buffer, int32_t *length, int arg)
988 /*                                                                          */
989 /*  Description:    Uncompress ASCII ACA data in "statement buffer".        */
990 /*                  Store resulting uncompressed literal data in global var */
991 /*                  urj_jam_literal_aca_buffer                                  */
992 /*                                                                          */
993 /*  Returns:        JAMC_SUCCESS for success, else appropriate error        */
994 /*                                                                          */
995 /****************************************************************************/
996 {
997     int bit = 0;
998     int value = 0;
999     int index = 0;
1000     int index2 = 0;
1001     int i = 0;
1002     int j = 0;
1003     int long_count = 0;
1004     int32_t binary_compressed_length = 0L;
1005     int32_t uncompressed_length = 0L;
1006     char *buffer = NULL;
1007     int32_t *long_ptr = NULL;
1008     int32_t out_size = 0L;
1009     int32_t address = 0L;
1010     JAM_RETURN_TYPE status = JAMC_SUCCESS;
1011 
1012     if ((arg < 0) || (arg >= JAMC_MAX_LITERAL_ARRAYS))
1013     {
1014         status = JAMC_INTERNAL_ERROR;
1015     }
1016 
1017     /* remove all white space */
1018     while (statement_buffer[index] != JAMC_NULL_CHAR)
1019     {
1020         if ((!isspace (statement_buffer[index])) &&
1021             (statement_buffer[index] != JAMC_TAB_CHAR) &&
1022             (statement_buffer[index] != JAMC_RETURN_CHAR) &&
1023             (statement_buffer[index] != JAMC_NEWLINE_CHAR))
1024         {
1025             statement_buffer[index2] = statement_buffer[index];
1026             ++index2;
1027         }
1028         ++index;
1029     }
1030     statement_buffer[index2] = JAMC_NULL_CHAR;
1031 
1032     /* convert 6-bit encoded characters to binary -- in the same buffer */
1033     index = 0;
1034     while ((status == JAMC_SUCCESS) &&
1035            (isalnum (statement_buffer[index]) ||
1036             (statement_buffer[index] == JAMC_AT_CHAR) ||
1037             (statement_buffer[index] == JAMC_UNDERSCORE_CHAR)))
1038     {
1039         value = urj_jam_6bit_char (statement_buffer[index]);
1040         statement_buffer[index] = 0;
1041 
1042         if (value == -1)
1043         {
1044             status = JAMC_SYNTAX_ERROR;
1045         }
1046         else
1047         {
1048             for (bit = 0; bit < 6; ++bit)
1049             {
1050                 if (value & (1 << (bit % 6)))
1051                 {
1052                     statement_buffer[address >> 3] |= (1L << (address & 7));
1053                 }
1054                 else
1055                 {
1056                     statement_buffer[address >> 3] &=
1057                         ~(unsigned int) (1 << (address & 7));
1058                 }
1059                 ++address;
1060             }
1061         }
1062 
1063         ++index;
1064     }
1065 
1066     if ((status == JAMC_SUCCESS) &&
1067         (statement_buffer[index] != JAMC_NULL_CHAR))
1068     {
1069         status = JAMC_SYNTAX_ERROR;
1070     }
1071 
1072     /* Compute length of binary data string in statement_buffer */
1073     binary_compressed_length = (address >> 3) + ((address & 7) ? 1 : 0);
1074 
1075     /* Get uncompressed length from first DWORD of compressed data */
1076     uncompressed_length = ((((int32_t) statement_buffer[3] << 24L) &
1077                             0xff000000L) | (((int32_t) statement_buffer[2] <<
1078                                              16L) & 0x00ff0000L) | (((int32_t)
1079                                                                      statement_buffer
1080                                                                      [1] <<
1081                                                                      8L) &
1082                                                                     0x0000ff00L)
1083                            | (((int32_t) statement_buffer[0]) & 0x000000ffL));
1084 
1085     /* Allocate memory for literal binary data */
1086     if (status == JAMC_SUCCESS)
1087     {
1088         buffer = malloc (uncompressed_length + 4);
1089         long_ptr = (int32_t *) malloc (uncompressed_length + 4);
1090 
1091         if ((buffer == NULL) || (long_ptr == NULL))
1092         {
1093             status = JAMC_OUT_OF_MEMORY;
1094         }
1095     }
1096 
1097     /* Uncompress encoded binary into literal binary data */
1098     out_size = urj_jam_uncompress (statement_buffer,
1099                                binary_compressed_length,
1100                                buffer, uncompressed_length, urj_jam_version);
1101 
1102     if (out_size != uncompressed_length)
1103     {
1104         status = JAMC_SYNTAX_ERROR;
1105     }
1106 
1107     if (status == JAMC_SUCCESS)
1108     {
1109         /*
1110          *      Convert uncompressed data to array of int32_t integers
1111          */
1112         long_count = (out_size + 3) / 4;        /* number of longs */
1113 
1114         for (i = 0; i < long_count; ++i)
1115         {
1116             j = i * 4;
1117             long_ptr[i] = ((((int32_t) buffer[j + 3] << 24L) & 0xff000000L) |
1118                            (((int32_t) buffer[j + 2] << 16L) & 0x00ff0000L) |
1119                            (((int32_t) buffer[j + 1] << 8L) & 0x0000ff00L) |
1120                            (((int32_t) buffer[j]) & 0x000000ffL));
1121         }
1122 
1123         urj_jam_literal_aca_buffer[arg] = long_ptr;
1124 
1125         if (output_buffer != NULL)
1126             *output_buffer = long_ptr;
1127 
1128         if (length != NULL)
1129             *length = uncompressed_length * 8L;
1130     }
1131 
1132     if (buffer != NULL)
1133         free (buffer);
1134 
1135     /* urj_jam_literal_aca_buffer[arg] will be freed later */
1136 
1137     return status;
1138 }
1139 
1140 /****************************************************************************/
1141 /*                                                                          */
1142 
urj_jam_get_array_argument(char * statement_buffer,JAMS_SYMBOL_RECORD ** symbol_record,int32_t ** literal_array_data,int32_t * start_index,int32_t * stop_index,int arg)1143 JAM_RETURN_TYPE urj_jam_get_array_argument
1144     (char *statement_buffer,
1145      JAMS_SYMBOL_RECORD **symbol_record,
1146      int32_t **literal_array_data,
1147      int32_t *start_index, int32_t *stop_index, int arg)
1148 /*                                                                          */
1149 /*  Description:    Looks for a sub-range-indexed array argument in the     */
1150 /*                  statement buffer.  Calls expression parser to evaluate  */
1151 /*                  the start_index and end_index arguments.                */
1152 /*                                                                          */
1153 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
1154 /*                                                                          */
1155 /****************************************************************************/
1156 {
1157     int index = 0;
1158     int expr_begin = 0;
1159     int expr_end = 0;
1160     int bracket_count = 0;
1161     int32_t literal_array_length = 0;
1162     char save_ch = 0;
1163     JAMS_SYMBOL_RECORD *tmp_symbol_rec = NULL;
1164     JAMS_HEAP_RECORD *heap_record = NULL;
1165     JAME_EXPRESSION_TYPE expr_type = JAM_ILLEGAL_EXPR_TYPE;
1166     JAM_RETURN_TYPE status = JAMC_SUCCESS;
1167 
1168     /* first look for literal array constant */
1169     while ((isspace (statement_buffer[index])) &&
1170            (index < JAMC_MAX_STATEMENT_LENGTH))
1171     {
1172         ++index;                /* skip over white space */
1173     }
1174 
1175     if ((urj_jam_version == 2) && (statement_buffer[index] == JAMC_POUND_CHAR))
1176     {
1177         /* literal array, binary representation */
1178         *symbol_record = NULL;
1179         ++index;
1180         while ((isspace (statement_buffer[index])) &&
1181                (index < JAMC_MAX_STATEMENT_LENGTH))
1182         {
1183             ++index;            /* skip over white space */
1184         }
1185         expr_begin = index;
1186 
1187         while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
1188                (statement_buffer[index] != JAMC_COMMA_CHAR) &&
1189                (statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
1190                (index < JAMC_MAX_STATEMENT_LENGTH))
1191         {
1192             ++index;
1193         }
1194         while ((index > expr_begin)
1195                && isspace (statement_buffer[index - 1]))
1196         {
1197             --index;
1198         }
1199         expr_end = index;
1200         save_ch = statement_buffer[expr_end];
1201         statement_buffer[expr_end] = JAMC_NULL_CHAR;
1202         status = urj_jam_convert_literal_binary (&statement_buffer[expr_begin],
1203                                              literal_array_data,
1204                                              &literal_array_length, arg);
1205         statement_buffer[expr_end] = save_ch;
1206 
1207         *start_index = 0L;
1208         *stop_index = literal_array_length - 1;
1209     }
1210     else if ((urj_jam_version == 2) &&
1211              (statement_buffer[index] == JAMC_DOLLAR_CHAR))
1212     {
1213         /* literal array, hex representation */
1214         *symbol_record = NULL;
1215         ++index;
1216         while ((isspace (statement_buffer[index])) &&
1217                (index < JAMC_MAX_STATEMENT_LENGTH))
1218         {
1219             ++index;            /* skip over white space */
1220         }
1221         expr_begin = index;
1222 
1223         while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
1224                (statement_buffer[index] != JAMC_COMMA_CHAR) &&
1225                (statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
1226                (index < JAMC_MAX_STATEMENT_LENGTH))
1227         {
1228             ++index;
1229         }
1230         while ((index > expr_begin)
1231                && isspace (statement_buffer[index - 1]))
1232         {
1233             --index;
1234         }
1235         expr_end = index;
1236         save_ch = statement_buffer[expr_end];
1237         statement_buffer[expr_end] = JAMC_NULL_CHAR;
1238         status = urj_jam_convert_literal_array (&statement_buffer[expr_begin],
1239                                             literal_array_data,
1240                                             &literal_array_length, arg);
1241         statement_buffer[expr_end] = save_ch;
1242 
1243         *start_index = 0L;
1244         *stop_index = literal_array_length - 1;
1245     }
1246     else if ((urj_jam_version == 2) && (statement_buffer[index] == JAMC_AT_CHAR))
1247     {
1248         /* literal array, ACA representation */
1249         *symbol_record = NULL;
1250         ++index;
1251         while ((isspace (statement_buffer[index])) &&
1252                (index < JAMC_MAX_STATEMENT_LENGTH))
1253         {
1254             ++index;            /* skip over white space */
1255         }
1256         expr_begin = index;
1257 
1258         while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
1259                (statement_buffer[index] != JAMC_COMMA_CHAR) &&
1260                (statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
1261                (index < JAMC_MAX_STATEMENT_LENGTH))
1262         {
1263             ++index;
1264         }
1265         while ((index > expr_begin)
1266                && isspace (statement_buffer[index - 1]))
1267         {
1268             --index;
1269         }
1270         expr_end = index;
1271         save_ch = statement_buffer[expr_end];
1272         statement_buffer[expr_end] = JAMC_NULL_CHAR;
1273         status = urj_jam_convert_literal_aca (&statement_buffer[expr_begin],
1274                                           literal_array_data,
1275                                           &literal_array_length, arg);
1276         statement_buffer[expr_end] = save_ch;
1277 
1278         *start_index = 0L;
1279         *stop_index = literal_array_length - 1;
1280     }
1281     else if ((urj_jam_version == 2) &&
1282              (strncmp (&statement_buffer[index], "BOOL(", 5) == 0))
1283     {
1284         /*
1285          *      Convert integer expression to Boolean array
1286          */
1287         expr_begin = index + 4;
1288         while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
1289                (statement_buffer[index] != JAMC_COMMA_CHAR) &&
1290                (statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
1291                (index < JAMC_MAX_STATEMENT_LENGTH))
1292         {
1293             ++index;
1294         }
1295 
1296         expr_end = index;
1297         ++index;
1298 
1299         if (expr_end > expr_begin)
1300         {
1301             save_ch = statement_buffer[expr_end];
1302             statement_buffer[expr_end] = JAMC_NULL_CHAR;
1303             status = urj_jam_evaluate_expression (&statement_buffer[expr_begin],
1304                                               &urj_jam_literal_array_buffer[arg],
1305                                               &expr_type);
1306             statement_buffer[expr_end] = save_ch;
1307         }
1308 
1309         /*
1310          *      Check for integer expression
1311          */
1312         if ((status == JAMC_SUCCESS) &&
1313             (expr_type != JAM_INTEGER_EXPR) &&
1314             (expr_type != JAM_INT_OR_BOOL_EXPR))
1315         {
1316             status = JAMC_TYPE_MISMATCH;
1317         }
1318 
1319         if (status == JAMC_SUCCESS)
1320         {
1321             *symbol_record = NULL;
1322             *literal_array_data = &urj_jam_literal_array_buffer[arg];
1323             *start_index = 0L;
1324             *stop_index = 31L;
1325         }
1326     }
1327     else if ((urj_jam_version != 2) && (isdigit (statement_buffer[index])))
1328     {
1329         /* it is a literal array constant */
1330         *symbol_record = NULL;
1331         expr_begin = index;
1332 
1333         while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
1334                (statement_buffer[index] != JAMC_COMMA_CHAR) &&
1335                (statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
1336                (index < JAMC_MAX_STATEMENT_LENGTH))
1337         {
1338             ++index;
1339         }
1340         while ((index > expr_begin)
1341                && isspace (statement_buffer[index - 1]))
1342         {
1343             --index;
1344         }
1345         expr_end = index;
1346         save_ch = statement_buffer[expr_end];
1347         statement_buffer[expr_end] = JAMC_NULL_CHAR;
1348         status = urj_jam_convert_literal_array (&statement_buffer[expr_begin],
1349                                             literal_array_data,
1350                                             &literal_array_length, arg);
1351         statement_buffer[expr_end] = save_ch;
1352 
1353         *start_index = 0L;
1354         *stop_index = literal_array_length - 1;
1355     }
1356     else
1357     {
1358         /* it is not a literal constant, look for array variable */
1359         *literal_array_data = NULL;
1360 
1361         while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
1362                (statement_buffer[index] != JAMC_LBRACKET_CHAR) &&
1363                (index < JAMC_MAX_STATEMENT_LENGTH))
1364         {
1365             ++index;
1366         }
1367 
1368         if (statement_buffer[index] != JAMC_LBRACKET_CHAR)
1369         {
1370             status = JAMC_SYNTAX_ERROR;
1371         }
1372         else
1373         {
1374             expr_end = index;
1375             ++index;
1376 
1377             save_ch = statement_buffer[expr_end];
1378             statement_buffer[expr_end] = JAMC_NULL_CHAR;
1379             status = urj_jam_get_symbol_record (&statement_buffer[expr_begin],
1380                                             &tmp_symbol_rec);
1381             statement_buffer[expr_end] = save_ch;
1382 
1383             if (status == JAMC_SUCCESS)
1384             {
1385                 *symbol_record = tmp_symbol_rec;
1386 
1387                 if ((tmp_symbol_rec->type != JAM_BOOLEAN_ARRAY_WRITABLE) &&
1388                     (tmp_symbol_rec->type != JAM_BOOLEAN_ARRAY_INITIALIZED))
1389                 {
1390                     status = JAMC_TYPE_MISMATCH;
1391                 }
1392                 else
1393                 {
1394                     /* it is a Boolean array variable */
1395                     while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
1396                            (statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
1397                            ((statement_buffer[index] != JAMC_RBRACKET_CHAR) ||
1398                             (bracket_count > 0)) &&
1399                            (index < JAMC_MAX_STATEMENT_LENGTH))
1400                     {
1401                         if (statement_buffer[index] == JAMC_LBRACKET_CHAR)
1402                         {
1403                             ++bracket_count;
1404                         }
1405                         else if (statement_buffer[index] ==
1406                                  JAMC_RBRACKET_CHAR)
1407                         {
1408                             --bracket_count;
1409                         }
1410 
1411                         ++index;
1412                     }
1413 
1414                     if (statement_buffer[index] != JAMC_RBRACKET_CHAR)
1415                     {
1416                         status = JAMC_SYNTAX_ERROR;
1417                     }
1418                     else
1419                     {
1420                         statement_buffer[index] = JAMC_NULL_CHAR;
1421 
1422                         status = urj_jam_get_array_subrange (tmp_symbol_rec,
1423                                                          &statement_buffer
1424                                                          [expr_end + 1],
1425                                                          start_index,
1426                                                          stop_index);
1427                         statement_buffer[index] = JAMC_RBRACKET_CHAR;
1428                         ++index;
1429 
1430                         if (status == JAMC_SUCCESS)
1431                         {
1432                             heap_record = (JAMS_HEAP_RECORD *)
1433                                 tmp_symbol_rec->value;
1434 
1435                             if (heap_record == NULL)
1436                             {
1437                                 status = JAMC_INTERNAL_ERROR;
1438                             }
1439                             else if ((*start_index < 0) || (*stop_index < 0)
1440                                      || (*start_index >=
1441                                          heap_record->dimension)
1442                                      || (*stop_index >=
1443                                          heap_record->dimension))
1444                             {
1445                                 status = JAMC_BOUNDS_ERROR;
1446                             }
1447                             else
1448                             {
1449                                 while (isspace (statement_buffer[index]))
1450                                 {
1451                                     ++index;
1452                                 }
1453 
1454                                 /* there should be no more characters */
1455                                 if (statement_buffer[index] != JAMC_NULL_CHAR)
1456                                 {
1457                                     status = JAMC_SYNTAX_ERROR;
1458                                 }
1459                             }
1460                         }
1461                     }
1462                 }
1463             }
1464         }
1465     }
1466 
1467     return status;
1468 }
1469 
1470 /****************************************************************************/
1471 /*                                                                          */
1472 
urj_jam_find_argument(char * statement_buffer,int * begin,int * end,int * delimiter)1473 JAM_RETURN_TYPE urj_jam_find_argument
1474     (char *statement_buffer, int *begin, int *end, int *delimiter)
1475 /*                                                                          */
1476 /*  Description:    Finds the next argument in the statement buffer, where  */
1477 /*                  the delimiters are COLON or SEMICOLON.  Returns indices */
1478 /*                  of begin and end of argument, and the delimiter after   */
1479 /*                  the argument.                                           */
1480 /*                                                                          */
1481 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
1482 /*                                                                          */
1483 /****************************************************************************/
1484 {
1485     int index = 0;
1486     JAM_RETURN_TYPE status = JAMC_SUCCESS;
1487 
1488     while ((isspace (statement_buffer[index])) &&
1489            (index < JAMC_MAX_STATEMENT_LENGTH))
1490     {
1491         ++index;                /* skip over white space */
1492     }
1493 
1494     *begin = index;
1495 
1496     while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
1497            (statement_buffer[index] != JAMC_COMMA_CHAR) &&
1498            (statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
1499            (index < JAMC_MAX_STATEMENT_LENGTH))
1500     {
1501         ++index;
1502     }
1503 
1504     if ((statement_buffer[index] != JAMC_COMMA_CHAR) &&
1505         (statement_buffer[index] != JAMC_SEMICOLON_CHAR))
1506     {
1507         status = JAMC_SYNTAX_ERROR;
1508     }
1509     else
1510     {
1511         *delimiter = index;     /* delimiter is position of comma or semicolon */
1512 
1513         while (isspace (statement_buffer[index - 1]))
1514         {
1515             --index;            /* skip backwards over white space */
1516         }
1517 
1518         *end = index;           /* end is position after last argument character */
1519     }
1520 
1521     return status;
1522 }
1523 
1524 /****************************************************************************/
1525 /*                                                                          */
1526 
1527 JAM_RETURN_TYPE
urj_jam_process_uses_item(char * block_name)1528 urj_jam_process_uses_item (char *block_name)
1529 /*                                                                          */
1530 /*  Description:    Checks validity of one block-name from a USES clause.   */
1531 /*                  If it is a data block name, initialize the data block.  */
1532 /*                                                                          */
1533 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
1534 /*                                                                          */
1535 /****************************************************************************/
1536 {
1537     int index = 0;
1538     char save_ch = 0;
1539     JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
1540     JAMS_SYMBOL_RECORD *symbol_record = NULL;
1541     int32_t current_position = 0L;
1542     int32_t return_position = urj_jam_next_statement_position;
1543     int32_t block_position = -1L;
1544     char block_buffer[JAMC_MAX_NAME_LENGTH + 1];
1545     char label_buffer[JAMC_MAX_NAME_LENGTH + 1];
1546     char *statement_buffer = NULL;
1547     JAME_INSTRUCTION instruction_code = JAM_ILLEGAL_INSTR;
1548     BOOL found = false;
1549     BOOL enddata = false;
1550     JAMS_STACK_RECORD *original_stack_position = NULL;
1551     BOOL reuse_statement_buffer = false;
1552     JAMS_SYMBOL_RECORD *tmp_current_block = urj_jam_current_block;
1553     JAME_PHASE_TYPE tmp_phase = urj_jam_phase;
1554     BOOL done = false;
1555     int exit_code = 0;
1556 
1557     statement_buffer = malloc (JAMC_MAX_STATEMENT_LENGTH + 1024);
1558 
1559     if (statement_buffer == NULL)
1560     {
1561         status = JAMC_OUT_OF_MEMORY;
1562     }
1563     else if (isalpha (block_name[index]))
1564     {
1565         /* locate block name */
1566         while ((jam_is_name_char (block_name[index])) &&
1567                (index < JAMC_MAX_STATEMENT_LENGTH))
1568         {
1569             ++index;            /* skip over block name */
1570         }
1571 
1572         /*
1573          *      Look in symbol table for block name
1574          */
1575         save_ch = block_name[index];
1576         block_name[index] = JAMC_NULL_CHAR;
1577         strcpy (block_buffer, block_name);
1578         block_name[index] = save_ch;
1579         status = urj_jam_get_symbol_record (block_buffer, &symbol_record);
1580 
1581         if ((status == JAMC_SUCCESS) &&
1582             ((symbol_record->type == JAM_PROCEDURE_BLOCK) ||
1583              (symbol_record->type == JAM_DATA_BLOCK)))
1584         {
1585             /*
1586              *      Name is defined - get the address of the block
1587              */
1588             block_position = symbol_record->position;
1589         }
1590         else if (status == JAMC_UNDEFINED_SYMBOL)
1591         {
1592             /*
1593              *      Block name is not defined... may be a forward reference.
1594              *      Search through the file to find the symbol.
1595              */
1596             current_position = urj_jam_current_statement_position;
1597 
1598             status = JAMC_SUCCESS;
1599 
1600             while ((!found) && (status == JAMC_SUCCESS))
1601             {
1602                 /*
1603                  *      Get statements without executing them
1604                  */
1605                 status = urj_jam_get_statement (statement_buffer, label_buffer);
1606 
1607                 if ((status == JAMC_SUCCESS) &&
1608                     (label_buffer[0] != JAMC_NULL_CHAR) && (urj_jam_version != 2))
1609                 {
1610                     /*
1611                      *      If there is a label, add it to the symbol table
1612                      */
1613                     status = urj_jam_add_symbol (JAM_LABEL, label_buffer, 0L,
1614                                              urj_jam_current_statement_position);
1615                 }
1616 
1617                 /*
1618                  *      Is this a PROCEDURE or DATA statement?
1619                  */
1620                 if (status == JAMC_SUCCESS)
1621                 {
1622                     instruction_code = urj_jam_get_instruction (statement_buffer);
1623 
1624                     switch (instruction_code)
1625                     {
1626                     case JAM_DATA_INSTR:
1627                         status = urj_jam_process_data (statement_buffer);
1628 
1629                         /* check if this is the block we want to process */
1630                         if (status == JAMC_SUCCESS)
1631                         {
1632                             status = urj_jam_get_symbol_record (block_buffer,
1633                                                             &symbol_record);
1634 
1635                             if (status == JAMC_SUCCESS)
1636                             {
1637                                 found = true;
1638                                 block_position = symbol_record->position;
1639                             }
1640                             else if (status == JAMC_UNDEFINED_SYMBOL)
1641                             {
1642                                 /* ignore undefined symbol errors */
1643                                 status = JAMC_SUCCESS;
1644                             }
1645                         }
1646                         break;
1647 
1648                     case JAM_PROCEDURE_INSTR:
1649                         status = urj_jam_process_procedure (statement_buffer);
1650 
1651                         /* check if this is the block we want to process */
1652                         if (status == JAMC_SUCCESS)
1653                         {
1654                             status = urj_jam_get_symbol_record (block_buffer,
1655                                                             &symbol_record);
1656 
1657                             if (status == JAMC_SUCCESS)
1658                             {
1659                                 found = true;
1660                                 block_position = symbol_record->position;
1661                             }
1662                             else if (status == JAMC_UNDEFINED_SYMBOL)
1663                             {
1664                                 /* ignore undefined symbol errors */
1665                                 status = JAMC_SUCCESS;
1666                             }
1667                         }
1668                         break;
1669                     default:
1670                         break;
1671                     }
1672                 }
1673             }
1674 
1675             if (!found)
1676             {
1677                 /* label was not found -- report "undefined symbol" */
1678                 /* rather than "unexpected EOF" */
1679                 status = JAMC_UNDEFINED_SYMBOL;
1680 
1681                 /* seek to location of the ACTION or PROCEDURE statement */
1682                 /* that caused the error */
1683                 urj_jam_seek (current_position);
1684                 urj_jam_current_file_position = current_position;
1685                 urj_jam_current_statement_position = current_position;
1686             }
1687         }
1688 
1689         if ((status == JAMC_SUCCESS) &&
1690             ((block_position == (-1L)) || (symbol_record == NULL)))
1691         {
1692             status = JAMC_INTERNAL_ERROR;
1693         }
1694 
1695         if ((status == JAMC_SUCCESS) &&
1696             (symbol_record->type != JAM_PROCEDURE_BLOCK) &&
1697             (symbol_record->type != JAM_DATA_BLOCK))
1698         {
1699             status = JAMC_SYNTAX_ERROR;
1700         }
1701 
1702         /*
1703          *      Call a data block to initialize the variables inside
1704          */
1705         if ((status == JAMC_SUCCESS) &&
1706             (symbol_record->type == JAM_DATA_BLOCK) &&
1707             (symbol_record->value == 0))
1708         {
1709             /*
1710              *      Push a CALL record onto the stack
1711              */
1712             if (status == JAMC_SUCCESS)
1713             {
1714                 original_stack_position = urj_jam_peek_stack_record ();
1715                 status = urj_jam_push_callret_record (return_position);
1716             }
1717 
1718             /*
1719              *      Now seek to the desired position so we can execute that
1720              *      statement next
1721              */
1722             if (status == JAMC_SUCCESS)
1723             {
1724                 if (urj_jam_seek (block_position) == 0)
1725                 {
1726                     urj_jam_current_file_position = block_position;
1727                 }
1728                 else
1729                 {
1730                     /* seek failed */
1731                     status = JAMC_IO_ERROR;
1732                 }
1733             }
1734 
1735             /*
1736              *      Set urj_jam_current_block to the data block about to be executed
1737              */
1738             if (status == JAMC_SUCCESS)
1739             {
1740                 urj_jam_current_block = symbol_record;
1741                 urj_jam_phase = JAM_DATA_PHASE;
1742             }
1743 
1744             /*
1745              *      Get program statements and execute them
1746              */
1747             while ((!(done)) && (!enddata) && (status == JAMC_SUCCESS))
1748             {
1749                 if (!reuse_statement_buffer)
1750                 {
1751                     status = urj_jam_get_statement
1752                         (statement_buffer, label_buffer);
1753 
1754                     if ((status == JAMC_SUCCESS)
1755                         && (label_buffer[0] != JAMC_NULL_CHAR))
1756                     {
1757                         status = urj_jam_add_symbol
1758                             (JAM_LABEL,
1759                              label_buffer,
1760                              0L, urj_jam_current_statement_position);
1761                     }
1762                 }
1763                 else
1764                 {
1765                     /* statement buffer will be reused -- clear the flag */
1766                     reuse_statement_buffer = false;
1767                 }
1768 
1769                 if (status == JAMC_SUCCESS)
1770                 {
1771                     status = urj_jam_execute_statement
1772                         (statement_buffer,
1773                          &done, &reuse_statement_buffer, &exit_code);
1774 
1775                     if ((status == JAMC_SUCCESS) &&
1776                         (urj_jam_get_instruction (statement_buffer)
1777                          == JAM_ENDDATA_INSTR) &&
1778                         (urj_jam_peek_stack_record () == original_stack_position))
1779                     {
1780                         enddata = true;
1781                     }
1782                 }
1783             }
1784 
1785             if (done && (status == JAMC_SUCCESS))
1786             {
1787                 /* an EXIT statement was processed -- impossible! */
1788                 status = JAMC_INTERNAL_ERROR;
1789             }
1790 
1791             /* indicate that this data block has been initialized */
1792             symbol_record->value = 1;
1793         }
1794     }
1795 
1796     urj_jam_current_block = tmp_current_block;
1797     urj_jam_phase = tmp_phase;
1798 
1799     if (statement_buffer != NULL)
1800         free (statement_buffer);
1801 
1802     return status;
1803 }
1804 
1805 JAM_RETURN_TYPE
urj_jam_process_uses_list(char * uses_list)1806 urj_jam_process_uses_list (char *uses_list)
1807 {
1808     JAM_RETURN_TYPE status = JAMC_SUCCESS;
1809     int name_begin = 0;
1810     int name_end = 0;
1811     int index = 0;
1812     char save_ch = 0;
1813 
1814     urj_jam_checking_uses_list = true;
1815 
1816     while ((status == JAMC_SUCCESS) &&
1817            (uses_list[index] != JAMC_SEMICOLON_CHAR) &&
1818            (uses_list[index] != 0x0) && (index < JAMC_MAX_STATEMENT_LENGTH))
1819     {
1820         while ((isspace (uses_list[index])) &&
1821                (index < JAMC_MAX_STATEMENT_LENGTH))
1822         {
1823             ++index;            /* skip over white space */
1824         }
1825 
1826         name_begin = index;
1827 
1828         while ((jam_is_name_char (uses_list[index])) &&
1829                (index < JAMC_MAX_STATEMENT_LENGTH))
1830         {
1831             ++index;            /* skip over procedure name */
1832         }
1833 
1834         name_end = index;
1835 
1836         while ((isspace (uses_list[index])) &&
1837                (index < JAMC_MAX_STATEMENT_LENGTH))
1838         {
1839             ++index;            /* skip over white space */
1840         }
1841 
1842         if ((name_end > name_begin) &&
1843             ((uses_list[index] == JAMC_COMMA_CHAR) ||
1844              (uses_list[index] == JAMC_SEMICOLON_CHAR)))
1845         {
1846             save_ch = uses_list[name_end];
1847             uses_list[name_end] = JAMC_NULL_CHAR;
1848             status = urj_jam_process_uses_item (&uses_list[name_begin]);
1849             uses_list[name_end] = save_ch;
1850 
1851             if (uses_list[index] == JAMC_COMMA_CHAR)
1852             {
1853                 ++index;        /* skip over comma */
1854             }
1855         }
1856         else
1857         {
1858             status = JAMC_SYNTAX_ERROR;
1859         }
1860     }
1861 
1862     if ((status == JAMC_SUCCESS) && (uses_list[index] != JAMC_SEMICOLON_CHAR))
1863     {
1864         status = JAMC_SYNTAX_ERROR;
1865     }
1866 
1867     urj_jam_checking_uses_list = false;
1868 
1869     return status;
1870 }
1871 
1872 /****************************************************************************/
1873 /*                                                                          */
1874 
urj_jam_call_procedure(char * procedure_name,BOOL * done,int * exit_code)1875 JAM_RETURN_TYPE urj_jam_call_procedure
1876     (char *procedure_name, BOOL *done, int *exit_code)
1877 /*                                                                          */
1878 /*  Description:    Calls the specified procedure, and executes the         */
1879 /*                  statements in the procedure.                            */
1880 /*                                                                          */
1881 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
1882 /*                                                                          */
1883 /****************************************************************************/
1884 {
1885     int index = 0;
1886     char save_ch = 0;
1887     JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
1888     JAMS_SYMBOL_RECORD *symbol_record = NULL;
1889     JAME_INSTRUCTION instruction_code = JAM_ILLEGAL_INSTR;
1890     int32_t current_position = 0L;
1891     int32_t proc_position = -1L;
1892     int32_t return_position = urj_jam_next_statement_position;
1893     char procedure_buffer[JAMC_MAX_NAME_LENGTH + 1];
1894     char label_buffer[JAMC_MAX_NAME_LENGTH + 1];
1895     char *statement_buffer = NULL;
1896     BOOL found = false;
1897     BOOL endproc = false;
1898     JAMS_STACK_RECORD *original_stack_position = NULL;
1899     BOOL reuse_statement_buffer = false;
1900     JAMS_HEAP_RECORD *heap_record = NULL;
1901     JAMS_SYMBOL_RECORD *tmp_current_block = urj_jam_current_block;
1902     JAME_PHASE_TYPE tmp_phase = urj_jam_phase;
1903 
1904     statement_buffer = malloc (JAMC_MAX_STATEMENT_LENGTH + 1024);
1905 
1906     if (statement_buffer == NULL)
1907     {
1908         status = JAMC_OUT_OF_MEMORY;
1909     }
1910     else if (isalpha (procedure_name[index]))
1911     {
1912         /* locate procedure name */
1913         while ((jam_is_name_char (procedure_name[index])) &&
1914                (index < JAMC_MAX_STATEMENT_LENGTH))
1915         {
1916             ++index;            /* skip over procedure name */
1917         }
1918 
1919         /*
1920          *      Look in symbol table for procedure name
1921          */
1922         save_ch = procedure_name[index];
1923         procedure_name[index] = JAMC_NULL_CHAR;
1924         strcpy (procedure_buffer, procedure_name);
1925         procedure_name[index] = save_ch;
1926         status = urj_jam_get_symbol_record (procedure_buffer, &symbol_record);
1927 
1928         if ((status == JAMC_SUCCESS) &&
1929             (symbol_record->type == JAM_PROCEDURE_BLOCK))
1930         {
1931             /*
1932              *      Label is defined - get the address for the jump
1933              */
1934             proc_position = symbol_record->position;
1935         }
1936         else if (status == JAMC_UNDEFINED_SYMBOL)
1937         {
1938             /*
1939              *      Label is not defined... may be a forward reference.
1940              *      Search through the file to find the symbol.
1941              */
1942             current_position = urj_jam_current_statement_position;
1943 
1944             status = JAMC_SUCCESS;
1945 
1946             while ((!found) && (status == JAMC_SUCCESS))
1947             {
1948                 /*
1949                  *      Get statements without executing them
1950                  */
1951                 status = urj_jam_get_statement (statement_buffer, label_buffer);
1952 
1953                 if ((status == JAMC_SUCCESS) &&
1954                     (label_buffer[0] != JAMC_NULL_CHAR) && (urj_jam_version != 2))
1955                 {
1956                     /*
1957                      *      If there is a label, add it to the symbol table
1958                      */
1959                     status = urj_jam_add_symbol (JAM_LABEL, label_buffer, 0L,
1960                                              urj_jam_current_statement_position);
1961                 }
1962 
1963                 /*
1964                  *      Is this a PROCEDURE or DATA statement?
1965                  */
1966                 if (status == JAMC_SUCCESS)
1967                 {
1968                     instruction_code = urj_jam_get_instruction (statement_buffer);
1969 
1970                     switch (instruction_code)
1971                     {
1972                     case JAM_DATA_INSTR:
1973                         status = urj_jam_process_data (statement_buffer);
1974                         break;
1975 
1976                     case JAM_PROCEDURE_INSTR:
1977                         status = urj_jam_process_procedure (statement_buffer);
1978 
1979                         /* check if this is the procedure we want to call */
1980                         if (status == JAMC_SUCCESS)
1981                         {
1982                             status = urj_jam_get_symbol_record (procedure_buffer,
1983                                                             &symbol_record);
1984 
1985                             if (status == JAMC_SUCCESS)
1986                             {
1987                                 found = true;
1988                                 proc_position = symbol_record->position;
1989                             }
1990                             else if (status == JAMC_UNDEFINED_SYMBOL)
1991                             {
1992                                 /* ignore undefined symbol errors */
1993                                 status = JAMC_SUCCESS;
1994                             }
1995                         }
1996                         break;
1997                     default:
1998                         break;
1999                     }
2000                 }
2001             }
2002 
2003             if (!found)
2004             {
2005                 /* procedure was not found -- report "undefined symbol" */
2006                 /* rather than "unexpected EOF" */
2007                 status = JAMC_UNDEFINED_SYMBOL;
2008 
2009                 /* seek to location of the ACTION or CALL statement */
2010                 /* that caused the error */
2011                 urj_jam_seek (current_position);
2012                 urj_jam_current_file_position = current_position;
2013                 urj_jam_current_statement_position = current_position;
2014             }
2015         }
2016 
2017         if ((status == JAMC_SUCCESS) && (symbol_record->value != 0L))
2018         {
2019             heap_record = (JAMS_HEAP_RECORD *) symbol_record->value;
2020             status = urj_jam_process_uses_list ((char *) heap_record->data);
2021         }
2022 
2023         /*
2024          *      Push a CALL record onto the stack
2025          */
2026         if ((status == JAMC_SUCCESS) && (proc_position != (-1L)))
2027         {
2028             original_stack_position = urj_jam_peek_stack_record ();
2029             status = urj_jam_push_callret_record (return_position);
2030         }
2031 
2032         /*
2033          *      Now seek to the desired position so we can execute that
2034          *      statement next
2035          */
2036         if ((status == JAMC_SUCCESS) && (proc_position != (-1L)))
2037         {
2038             if (urj_jam_seek (proc_position) == 0)
2039             {
2040                 urj_jam_current_file_position = proc_position;
2041             }
2042             else
2043             {
2044                 /* seek failed */
2045                 status = JAMC_IO_ERROR;
2046             }
2047         }
2048     }
2049 
2050     /*
2051      *      Set urj_jam_current_block to the procedure about to be executed
2052      */
2053     if (status == JAMC_SUCCESS)
2054     {
2055         urj_jam_current_block = symbol_record;
2056         urj_jam_phase = JAM_PROCEDURE_PHASE;
2057     }
2058 
2059     /*
2060      *      Get program statements and execute them
2061      */
2062     while ((!(*done)) && (!endproc) && (status == JAMC_SUCCESS))
2063     {
2064         if (!reuse_statement_buffer)
2065         {
2066             status = urj_jam_get_statement (statement_buffer, label_buffer);
2067 
2068             if ((status == JAMC_SUCCESS)
2069                 && (label_buffer[0] != JAMC_NULL_CHAR))
2070             {
2071                 status = urj_jam_add_symbol
2072                     (JAM_LABEL,
2073                      label_buffer, 0L, urj_jam_current_statement_position);
2074             }
2075         }
2076         else
2077         {
2078             /* statement buffer will be reused -- clear the flag */
2079             reuse_statement_buffer = false;
2080         }
2081 
2082         if (status == JAMC_SUCCESS)
2083         {
2084             status = urj_jam_execute_statement
2085                 (statement_buffer, done, &reuse_statement_buffer, exit_code);
2086 
2087             if ((status == JAMC_SUCCESS) &&
2088                 (urj_jam_get_instruction (statement_buffer) == JAM_ENDPROC_INSTR)
2089                 && (urj_jam_peek_stack_record () == original_stack_position))
2090             {
2091                 endproc = true;
2092             }
2093         }
2094     }
2095 
2096     urj_jam_current_block = tmp_current_block;
2097     urj_jam_phase = tmp_phase;
2098 
2099     if (statement_buffer != NULL)
2100         free (statement_buffer);
2101 
2102     return status;
2103 }
2104 
urj_jam_call_procedure_from_action(char * procedure_name,BOOL * done,int * exit_code)2105 JAM_RETURN_TYPE urj_jam_call_procedure_from_action
2106     (char *procedure_name, BOOL *done, int *exit_code)
2107 {
2108     JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
2109     int index = 0;
2110     int procname_end = 0;
2111     int variable_begin = 0;
2112     int variable_end = 0;
2113     char save_ch = 0;
2114     BOOL call_it = false;
2115     BOOL init_value_set = false;
2116     int32_t init_value = 0L;
2117 
2118     if (isalpha (procedure_name[index]))
2119     {
2120         while ((jam_is_name_char (procedure_name[index])) &&
2121                (index < JAMC_MAX_STATEMENT_LENGTH))
2122         {
2123             ++index;            /* skip over procedure name */
2124         }
2125 
2126         procname_end = index;
2127         save_ch = procedure_name[procname_end];
2128         procedure_name[procname_end] = JAMC_NULL_CHAR;
2129 
2130         if (urj_jam_check_init_list (procedure_name, &init_value))
2131         {
2132             init_value_set = true;
2133         }
2134 
2135         procedure_name[procname_end] = save_ch;
2136 
2137         while ((isspace (procedure_name[index])) &&
2138                (index < JAMC_MAX_STATEMENT_LENGTH))
2139         {
2140             ++index;            /* skip over white space */
2141         }
2142 
2143         if (procedure_name[index] == JAMC_NULL_CHAR)
2144         {
2145             /*
2146              *      This is a mandatory procedure -- there is no
2147              *      OPTIONAL or RECOMMENDED keyword.  Just call it.
2148              */
2149             status = JAMC_SUCCESS;
2150             call_it = true;
2151         }
2152         else
2153         {
2154             variable_begin = index;
2155 
2156             while ((jam_is_name_char (procedure_name[index])) &&
2157                    (index < JAMC_MAX_STATEMENT_LENGTH))
2158             {
2159                 ++index;        /* skip over procedure name */
2160             }
2161 
2162             variable_end = index;
2163 
2164             while ((isspace (procedure_name[index])) &&
2165                    (index < JAMC_MAX_STATEMENT_LENGTH))
2166             {
2167                 ++index;        /* skip over white space */
2168             }
2169 
2170             if (procedure_name[index] == JAMC_NULL_CHAR)
2171             {
2172                 /* examine the keyword */
2173                 save_ch = procedure_name[variable_end];
2174                 procedure_name[variable_end] = JAMC_NULL_CHAR;
2175 
2176                 if (strcasecmp (&procedure_name[variable_begin], "OPTIONAL")
2177                     == 0)
2178                 {
2179                     /* OPTIONAL - don't call it unless specifically requested */
2180                     status = JAMC_SUCCESS;
2181                     call_it = false;
2182                     if (init_value_set && (init_value != 0))
2183                     {
2184                         /* it was requested -- call it */
2185                         call_it = true;
2186                     }
2187                 }
2188                 else if (strcasecmp
2189                          (&procedure_name[variable_begin],
2190                           "RECOMMENDED") == 0)
2191                 {
2192                     /* RECOMMENDED - call it unless specifically directed otherwise */
2193                     status = JAMC_SUCCESS;
2194                     call_it = true;
2195                     if (init_value_set && (init_value == 0))
2196                     {
2197                         /* it was declined -- don't call it */
2198                         call_it = false;
2199                     }
2200                 }
2201                 else
2202                 {
2203                     /* the string did not match "OPTIONAL" or "RECOMMENDED" */
2204                     status = JAMC_SYNTAX_ERROR;
2205                 }
2206 
2207                 procedure_name[variable_end] = save_ch;
2208             }
2209             else
2210             {
2211                 /* something else is lurking here -- syntax error */
2212                 status = JAMC_SYNTAX_ERROR;
2213             }
2214         }
2215     }
2216 
2217     if ((status == JAMC_SUCCESS) && call_it)
2218     {
2219         status = urj_jam_call_procedure (procedure_name, done, exit_code);
2220     }
2221 
2222     return status;
2223 }
2224 
urj_jam_call_procedure_from_procedure(char * procedure_name,BOOL * done,int * exit_code)2225 JAM_RETURN_TYPE urj_jam_call_procedure_from_procedure
2226     (char *procedure_name, BOOL *done, int *exit_code)
2227 {
2228     JAM_RETURN_TYPE status = JAMC_SCOPE_ERROR;
2229     JAMS_HEAP_RECORD *heap_record = NULL;
2230     char *uses_list = NULL;
2231     char save_ch = 0;
2232     int ch_index = 0;
2233     int name_begin = 0;
2234     int name_end = 0;
2235 
2236     if (urj_jam_version != 2)
2237     {
2238         status = JAMC_SUCCESS;
2239     }
2240     else
2241     {
2242         /*
2243          *      Check if procedure being called is listed in the
2244          *      "uses list", or is a recursive call to the calling
2245          *      procedure itself
2246          */
2247         if ((urj_jam_current_block != NULL) &&
2248             (urj_jam_current_block->type == JAM_PROCEDURE_BLOCK))
2249         {
2250             heap_record = (JAMS_HEAP_RECORD *) urj_jam_current_block->value;
2251 
2252             if (heap_record != NULL)
2253             {
2254                 uses_list = (char *) heap_record->data;
2255             }
2256 
2257             if (strcasecmp (procedure_name, urj_jam_current_block->name) == 0)
2258             {
2259                 /* any procedure may always call itself */
2260                 status = JAMC_SUCCESS;
2261             }
2262         }
2263 
2264         if ((status != JAMC_SUCCESS) && (uses_list != NULL))
2265         {
2266             name_begin = 0;
2267             ch_index = 0;
2268             while ((uses_list[ch_index] != JAMC_NULL_CHAR) &&
2269                    (status != JAMC_SUCCESS))
2270             {
2271                 name_end = 0;
2272                 while ((uses_list[ch_index] != JAMC_NULL_CHAR) &&
2273                        (!jam_is_name_char (uses_list[ch_index])))
2274                 {
2275                     ++ch_index;
2276                 }
2277                 if (jam_is_name_char (uses_list[ch_index]))
2278                 {
2279                     name_begin = ch_index;
2280                 }
2281                 while ((uses_list[ch_index] != JAMC_NULL_CHAR) &&
2282                        (jam_is_name_char (uses_list[ch_index])))
2283                 {
2284                     ++ch_index;
2285                 }
2286                 name_end = ch_index;
2287 
2288                 if (name_end > name_begin)
2289                 {
2290                     save_ch = uses_list[name_end];
2291                     uses_list[name_end] = JAMC_NULL_CHAR;
2292                     if (strcasecmp (&uses_list[name_begin],
2293                                      procedure_name) == 0)
2294                     {
2295                         /* symbol is in scope */
2296                         status = JAMC_SUCCESS;
2297                     }
2298                     uses_list[name_end] = save_ch;
2299                 }
2300             }
2301         }
2302     }
2303 
2304     if (status == JAMC_SUCCESS)
2305     {
2306         status = urj_jam_call_procedure (procedure_name, done, exit_code);
2307     }
2308 
2309     return status;
2310 }
2311 
2312 /****************************************************************************/
2313 /*                                                                          */
2314 
urj_jam_process_action(char * statement_buffer,BOOL * done,int * exit_code)2315 JAM_RETURN_TYPE urj_jam_process_action
2316     (char *statement_buffer, BOOL *done, int *exit_code)
2317 /*                                                                          */
2318 /*  Description:    Processes an ACTION statement.  Calls specified         */
2319 /*                  procedure blocks in sequence.                           */
2320 /*                                                                          */
2321 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
2322 /*                                                                          */
2323 /****************************************************************************/
2324 {
2325     JAM_RETURN_TYPE status = JAMC_SUCCESS;
2326     BOOL execute = false;
2327     int index = 0;
2328     int variable_begin = 0;
2329     int variable_end = 0;
2330     char save_ch = 0;
2331 
2332     if (urj_jam_version == 0)
2333         urj_jam_version = 2;
2334 
2335     if (urj_jam_version == 1)
2336         status = JAMC_SYNTAX_ERROR;
2337 
2338     if ((urj_jam_phase == JAM_UNKNOWN_PHASE) || (urj_jam_phase == JAM_NOTE_PHASE))
2339     {
2340         urj_jam_phase = JAM_ACTION_PHASE;
2341     }
2342 
2343     if ((urj_jam_version == 2) && (urj_jam_phase != JAM_ACTION_PHASE))
2344     {
2345         status = JAMC_PHASE_ERROR;
2346     }
2347 
2348     index = urj_jam_skip_instruction_name (statement_buffer);
2349 
2350     if (isalpha (statement_buffer[index]))
2351     {
2352         /*
2353          *      Get the action name
2354          */
2355         variable_begin = index;
2356         while ((jam_is_name_char (statement_buffer[index])) &&
2357                (index < JAMC_MAX_STATEMENT_LENGTH))
2358         {
2359             ++index;            /* skip over variable name */
2360         }
2361         variable_end = index;
2362 
2363         while ((isspace (statement_buffer[index])) &&
2364                (index < JAMC_MAX_STATEMENT_LENGTH))
2365         {
2366             ++index;            /* skip over white space */
2367         }
2368 
2369         save_ch = statement_buffer[variable_end];
2370         statement_buffer[variable_end] = JAMC_NULL_CHAR;
2371         if (urj_jam_action == NULL)
2372         {
2373             /*
2374              *      If no action name was specified, this is a fatal error
2375              */
2376             status = JAMC_ACTION_NOT_FOUND;
2377         }
2378         else if (strcasecmp (&statement_buffer[variable_begin],
2379                               urj_jam_action) == 0)
2380         {
2381             /* this action name matches the desired action name - execute it */
2382             execute = true;
2383             urj_jam_phase = JAM_PROCEDURE_PHASE;
2384         }
2385         statement_buffer[variable_end] = save_ch;
2386 
2387         if (execute && (statement_buffer[index] == JAMC_QUOTE_CHAR))
2388         {
2389             /*
2390              *      Get the action description string (if there is one)
2391              */
2392             ++index;            /* step over quote char */
2393             variable_begin = index;
2394 
2395             /* find matching quote */
2396             while ((statement_buffer[index] != JAMC_QUOTE_CHAR) &&
2397                    (statement_buffer[index] != JAMC_NULL_CHAR) &&
2398                    (index < JAMC_MAX_STATEMENT_LENGTH))
2399             {
2400                 ++index;
2401             }
2402 
2403             if (statement_buffer[index] == JAMC_QUOTE_CHAR)
2404             {
2405                 variable_end = index;
2406 
2407                 ++index;        /* skip over quote character */
2408 
2409                 while ((isspace (statement_buffer[index])) &&
2410                        (index < JAMC_MAX_STATEMENT_LENGTH))
2411                 {
2412                     ++index;    /* skip over white space */
2413                 }
2414             }
2415         }
2416 
2417         if (execute && (statement_buffer[index] == JAMC_EQUAL_CHAR))
2418         {
2419             ++index;            /* skip over equal character */
2420 
2421             /*
2422              *      Call procedures
2423              */
2424             while ((status == JAMC_SUCCESS) &&
2425                    (statement_buffer[index] != JAMC_NULL_CHAR) &&
2426                    (statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
2427                    (index < JAMC_MAX_STATEMENT_LENGTH))
2428             {
2429                 while ((isspace (statement_buffer[index])) &&
2430                        (index < JAMC_MAX_STATEMENT_LENGTH))
2431                 {
2432                     ++index;    /* skip over white space */
2433                 }
2434 
2435                 variable_begin = index;
2436 
2437                 while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
2438                        (statement_buffer[index] != JAMC_COMMA_CHAR) &&
2439                        (statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
2440                        (index < JAMC_MAX_STATEMENT_LENGTH))
2441                 {
2442                     ++index;
2443                 }
2444 
2445                 if ((statement_buffer[index] == JAMC_COMMA_CHAR) ||
2446                     (statement_buffer[index] == JAMC_SEMICOLON_CHAR))
2447                 {
2448                     variable_end = index;
2449 
2450                     save_ch = statement_buffer[variable_end];
2451                     statement_buffer[variable_end] = JAMC_NULL_CHAR;
2452                     status =
2453                         urj_jam_call_procedure_from_action (&statement_buffer
2454                                                         [variable_begin],
2455                                                         done, exit_code);
2456                     statement_buffer[variable_end] = save_ch;
2457                 }
2458 
2459                 if (statement_buffer[index] == JAMC_COMMA_CHAR)
2460                 {
2461                     ++index;    /* step over comma */
2462                 }
2463             }
2464 
2465             if ((status == JAMC_SUCCESS) && !(*done))
2466             {
2467                 *done = true;
2468                 *exit_code = 0; /* success */
2469             }
2470         }
2471     }
2472 
2473     return status;
2474 }
2475 
2476 /****************************************************************************/
2477 /*                                                                          */
2478 
2479 JAM_RETURN_TYPE
urj_jam_process_boolean(char * statement_buffer)2480 urj_jam_process_boolean (char *statement_buffer)
2481 /*                                                                          */
2482 /*  Description:    Processes a BOOLEAN variable declaration statement      */
2483 /*                                                                          */
2484 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
2485 /*                                                                          */
2486 /****************************************************************************/
2487 {
2488     int index = 0;
2489     int variable_begin = 0;
2490     int variable_end = 0;
2491     int dim_begin = 0;
2492     int dim_end = 0;
2493     int expr_begin = 0;
2494     int expr_end = 0;
2495     int delimiter = 0;
2496     int32_t dim_value = 0L;
2497     int32_t init_value = 0L;
2498     char save_ch = 0;
2499     JAME_EXPRESSION_TYPE expr_type = JAM_ILLEGAL_EXPR_TYPE;
2500     JAMS_SYMBOL_RECORD *symbol_record = NULL;
2501     JAMS_HEAP_RECORD *heap_record = NULL;
2502     JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
2503 
2504     if (urj_jam_version == 0)
2505         urj_jam_version = 1;
2506 
2507     if ((urj_jam_version == 2) &&
2508         (urj_jam_phase != JAM_PROCEDURE_PHASE) && (urj_jam_phase != JAM_DATA_PHASE))
2509     {
2510         return JAMC_PHASE_ERROR;
2511     }
2512 
2513     index = urj_jam_skip_instruction_name (statement_buffer);
2514 
2515     if (isalpha (statement_buffer[index]))
2516     {
2517         /* locate variable name */
2518         variable_begin = index;
2519         while ((jam_is_name_char (statement_buffer[index])) &&
2520                (index < JAMC_MAX_STATEMENT_LENGTH))
2521         {
2522             ++index;            /* skip over variable name */
2523         }
2524         variable_end = index;
2525 
2526         while ((isspace (statement_buffer[index])) &&
2527                (index < JAMC_MAX_STATEMENT_LENGTH))
2528         {
2529             ++index;            /* skip over white space */
2530         }
2531 
2532         if (statement_buffer[index] == JAMC_LBRACKET_CHAR)
2533         {
2534             /*
2535              *      Array declaration
2536              */
2537             dim_begin = index + 1;
2538             while ((statement_buffer[index] != JAMC_RBRACKET_CHAR) &&
2539                    (index < JAMC_MAX_STATEMENT_LENGTH))
2540             {
2541                 ++index;        /* find matching bracket */
2542             }
2543             if (statement_buffer[index] == JAMC_RBRACKET_CHAR)
2544             {
2545                 dim_end = index;
2546                 ++index;
2547             }
2548             while ((isspace (statement_buffer[index])) &&
2549                    (index < JAMC_MAX_STATEMENT_LENGTH))
2550             {
2551                 ++index;        /* skip over white space */
2552             }
2553 
2554             if (dim_end > dim_begin)
2555             {
2556                 save_ch = statement_buffer[dim_end];
2557                 statement_buffer[dim_end] = JAMC_NULL_CHAR;
2558                 status =
2559                     urj_jam_evaluate_expression (&statement_buffer[dim_begin],
2560                                              &dim_value, &expr_type);
2561                 statement_buffer[dim_end] = save_ch;
2562             }
2563 
2564             /*
2565              *      Check for integer expression
2566              */
2567             if ((status == JAMC_SUCCESS) &&
2568                 (expr_type != JAM_INTEGER_EXPR) &&
2569                 (expr_type != JAM_INT_OR_BOOL_EXPR))
2570             {
2571                 status = JAMC_TYPE_MISMATCH;
2572             }
2573 
2574             if (status == JAMC_SUCCESS)
2575             {
2576                 /*
2577                  *      Add the array name to the symbol table
2578                  */
2579                 save_ch = statement_buffer[variable_end];
2580                 statement_buffer[variable_end] = JAMC_NULL_CHAR;
2581                 status = urj_jam_add_symbol (JAM_BOOLEAN_ARRAY_WRITABLE,
2582                                          &statement_buffer[variable_begin],
2583                                          0L, urj_jam_current_statement_position);
2584 
2585                 /* get a pointer to the symbol record */
2586                 if (status == JAMC_SUCCESS)
2587                 {
2588                     status =
2589                         urj_jam_get_symbol_record (&statement_buffer
2590                                                [variable_begin],
2591                                                &symbol_record);
2592                 }
2593                 statement_buffer[variable_end] = save_ch;
2594             }
2595 
2596             /*
2597              *      Only initialize if array has not been initialized before
2598              */
2599             if ((status == JAMC_SUCCESS) &&
2600                 (symbol_record->type == JAM_BOOLEAN_ARRAY_WRITABLE) &&
2601                 (symbol_record->value == 0))
2602             {
2603                 if (statement_buffer[index] == JAMC_EQUAL_CHAR)
2604                 {
2605                     /*
2606                      *      Array has initialization data
2607                      */
2608                     symbol_record->type = JAM_BOOLEAN_ARRAY_INITIALIZED;
2609 
2610                     status = urj_jam_add_heap_record (symbol_record, &heap_record,
2611                                                   dim_value);
2612 
2613                     if (status == JAMC_SUCCESS)
2614                     {
2615                         symbol_record->value = (int32_t) heap_record;
2616 
2617                         /*
2618                          *      Initialize heap data for array
2619                          */
2620                         status = urj_jam_read_boolean_array_data (heap_record,
2621                                                               &statement_buffer
2622                                                               [index + 1]);
2623                     }
2624                 }
2625                 else if (statement_buffer[index] == JAMC_SEMICOLON_CHAR)
2626                 {
2627                     /*
2628                      *      Array has no initialization data.
2629                      *      Allocate a buffer on the heap:
2630                      */
2631                     status = urj_jam_add_heap_record (symbol_record, &heap_record,
2632                                                   dim_value);
2633 
2634                     if (status == JAMC_SUCCESS)
2635                     {
2636                         symbol_record->value = (int32_t) heap_record;
2637                     }
2638                 }
2639             }
2640         }
2641         else
2642         {
2643             /*
2644              *      Scalar variable declaration
2645              */
2646             if (statement_buffer[index] == JAMC_SEMICOLON_CHAR)
2647             {
2648                 status = JAMC_SUCCESS;
2649             }
2650             else if (statement_buffer[index] == JAMC_EQUAL_CHAR)
2651             {
2652                 /*
2653                  *      Evaluate initialization expression
2654                  */
2655                 ++index;
2656                 status = urj_jam_find_argument (&statement_buffer[index],
2657                                             &expr_begin, &expr_end,
2658                                             &delimiter);
2659 
2660                 expr_begin += index;
2661                 expr_end += index;
2662                 delimiter += index;
2663 
2664                 if ((status == JAMC_SUCCESS) &&
2665                     (statement_buffer[delimiter] != JAMC_SEMICOLON_CHAR))
2666                 {
2667                     status = JAMC_SYNTAX_ERROR;
2668                 }
2669 
2670                 if ((status == JAMC_SUCCESS) && (expr_end > expr_begin))
2671                 {
2672                     save_ch = statement_buffer[expr_end];
2673                     statement_buffer[expr_end] = JAMC_NULL_CHAR;
2674                     status =
2675                         urj_jam_evaluate_expression (&statement_buffer
2676                                                  [expr_begin], &init_value,
2677                                                  &expr_type);
2678                     statement_buffer[expr_end] = save_ch;
2679                 }
2680 
2681                 /*
2682                  *      Check for Boolean expression
2683                  */
2684                 if ((status == JAMC_SUCCESS) &&
2685                     (expr_type != JAM_BOOLEAN_EXPR) &&
2686                     (expr_type != JAM_INT_OR_BOOL_EXPR))
2687                 {
2688                     status = JAMC_TYPE_MISMATCH;
2689                 }
2690             }
2691 
2692             if (status == JAMC_SUCCESS)
2693             {
2694                 /*
2695                  *      Add the variable name to the symbol table
2696                  */
2697                 save_ch = statement_buffer[variable_end];
2698                 statement_buffer[variable_end] = JAMC_NULL_CHAR;
2699                 status = urj_jam_add_symbol (JAM_BOOLEAN_SYMBOL,
2700                                          &statement_buffer[variable_begin],
2701                                          init_value,
2702                                          urj_jam_current_statement_position);
2703                 statement_buffer[variable_end] = save_ch;
2704             }
2705         }
2706     }
2707 
2708     return status;
2709 }
2710 
2711 /****************************************************************************/
2712 /*                                                                          */
2713 
urj_jam_process_call_or_goto(char * statement_buffer,BOOL call_statement,BOOL * done,int * exit_code)2714 JAM_RETURN_TYPE urj_jam_process_call_or_goto
2715     (char *statement_buffer, BOOL call_statement, BOOL *done, int *exit_code)
2716 /*                                                                          */
2717 /*  Description:    Processes a CALL or GOTO statement.  If it is a CALL    */
2718 /*                  statement, a stack record is pushed onto the stack.     */
2719 /*                                                                          */
2720 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
2721 /*                                                                          */
2722 /****************************************************************************/
2723 {
2724     int index = 0;
2725     int label_begin = 0;
2726     int label_end = 0;
2727     char save_ch = 0;
2728     JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
2729     JAMS_SYMBOL_RECORD *symbol_record = NULL;
2730     JAME_SYMBOL_TYPE symbol_type = JAM_LABEL;
2731     int32_t current_position = 0L;
2732     int32_t goto_position = -1L;
2733     int32_t return_position = urj_jam_next_statement_position;
2734     char label_buffer[JAMC_MAX_NAME_LENGTH + 1];
2735     char goto_label[JAMC_MAX_NAME_LENGTH + 1];
2736     BOOL found = false;
2737 
2738     if (urj_jam_version == 0)
2739         urj_jam_version = 1;
2740 
2741     if ((urj_jam_version == 2) && (urj_jam_phase != JAM_PROCEDURE_PHASE))
2742     {
2743         return JAMC_PHASE_ERROR;
2744     }
2745 
2746     if ((urj_jam_version == 2) && call_statement)
2747     {
2748         symbol_type = JAM_PROCEDURE_BLOCK;
2749     }
2750 
2751     index = urj_jam_skip_instruction_name (statement_buffer);
2752 
2753     /*
2754      *      Extract the label name from the statement buffer.
2755      */
2756     if (isalpha (statement_buffer[index]) && !found)
2757     {
2758         /* locate label name */
2759         label_begin = index;
2760         while ((jam_is_name_char (statement_buffer[index])) &&
2761                (index < JAMC_MAX_STATEMENT_LENGTH))
2762         {
2763             ++index;            /* skip over label name */
2764         }
2765         label_end = index;
2766 
2767         save_ch = statement_buffer[label_end];
2768         statement_buffer[label_end] = JAMC_NULL_CHAR;
2769         strcpy (goto_label, &statement_buffer[label_begin]);
2770         statement_buffer[label_end] = save_ch;
2771 
2772         while ((isspace (statement_buffer[index])) &&
2773                (index < JAMC_MAX_STATEMENT_LENGTH))
2774         {
2775             ++index;            /* skip over white space */
2776         }
2777 
2778         if (statement_buffer[index] == JAMC_SEMICOLON_CHAR)
2779         {
2780             /*
2781              *      Look in symbol table for label
2782              */
2783             save_ch = statement_buffer[label_end];
2784             statement_buffer[label_end] = JAMC_NULL_CHAR;
2785             status =
2786                 urj_jam_get_symbol_record (&statement_buffer[label_begin],
2787                                        &symbol_record);
2788 
2789             if ((status == JAMC_SUCCESS) &&
2790                 (symbol_record->type == symbol_type))
2791             {
2792                 /*
2793                  *      Label is defined - get the address for the jump
2794                  */
2795                 goto_position = symbol_record->position;
2796             }
2797             else if (status == JAMC_UNDEFINED_SYMBOL)
2798             {
2799                 /*
2800                  *      Label is not defined... may be a forward reference.
2801                  *      Search through the file to find the symbol.
2802                  */
2803                 current_position = urj_jam_current_statement_position;
2804 
2805                 status = JAMC_SUCCESS;
2806 
2807                 while ((!found) && (status == JAMC_SUCCESS))
2808                 {
2809                     /*
2810                      *      Get statements without executing them
2811                      */
2812                     status =
2813                         urj_jam_get_statement (statement_buffer, label_buffer);
2814 
2815                     if ((status == JAMC_SUCCESS) &&
2816                         (label_buffer[0] != JAMC_NULL_CHAR))
2817                     {
2818                         /*
2819                          *      If there is a label, add it to the symbol table
2820                          */
2821                         status = urj_jam_add_symbol (JAM_LABEL, label_buffer, 0L,
2822                                                  urj_jam_current_statement_position);
2823 
2824                         /*
2825                          *      Is it the label we are looking for?
2826                          */
2827                         if ((status == JAMC_SUCCESS) &&
2828                             (strcmp (label_buffer, goto_label) == 0))
2829                         {
2830                             /*
2831                              *      We found the label we were looking for.
2832                              *      Get the address for the jump.
2833                              */
2834                             found = true;
2835                             goto_position = urj_jam_current_statement_position;
2836                         }
2837                     }
2838 
2839                     /*
2840                      *      In Jam 2.0, only search inside current procedure
2841                      */
2842                     if ((status == JAMC_SUCCESS) && (!found) &&
2843                         (urj_jam_version == 2)
2844                         && (urj_jam_get_instruction (statement_buffer) ==
2845                             JAM_ENDPROC_INSTR))
2846                     {
2847                         status = JAMC_UNDEFINED_SYMBOL;
2848                     }
2849                 }
2850 
2851                 if (!found)
2852                 {
2853                     /* label was not found -- report "undefined symbol" */
2854                     /* rather than "unexpected EOF" */
2855                     status = JAMC_UNDEFINED_SYMBOL;
2856 
2857                     /* seek to location of the CALL or GOTO statement */
2858                     /* which caused the error */
2859                     urj_jam_seek (current_position);
2860                     urj_jam_current_file_position = current_position;
2861                     urj_jam_current_statement_position = current_position;
2862                 }
2863             }
2864 
2865             statement_buffer[label_end] = save_ch;
2866 
2867             /*
2868              *      If this is a CALL statement (not a GOTO) then push a CALL
2869              *      record onto the stack
2870              */
2871             if ((call_statement) && (status == JAMC_SUCCESS) &&
2872                 (goto_position != (-1L)) && (urj_jam_version != 2))
2873             {
2874                 status = urj_jam_push_callret_record (return_position);
2875             }
2876 
2877             /*
2878              *      Now seek to the desired position so we can execute that
2879              *      statement next
2880              */
2881             if ((status == JAMC_SUCCESS) && (goto_position != (-1L)) &&
2882                 ((urj_jam_version != 2) || (!call_statement)))
2883             {
2884                 if (urj_jam_seek (goto_position) == 0)
2885                 {
2886                     urj_jam_current_file_position = goto_position;
2887                 }
2888                 else
2889                 {
2890                     /* seek failed */
2891                     status = JAMC_IO_ERROR;
2892                 }
2893             }
2894 
2895             /*
2896              *      Call a procedure block in Jam 2.0
2897              */
2898             if (call_statement && (urj_jam_version == 2))
2899             {
2900                 status =
2901                     urj_jam_call_procedure_from_procedure (goto_label, done,
2902                                                        exit_code);
2903             }
2904         }
2905     }
2906 
2907     return status;
2908 }
2909 
2910 JAM_RETURN_TYPE
urj_jam_process_data(char * statement_buffer)2911 urj_jam_process_data (char *statement_buffer)
2912 {
2913     int index = 0;
2914     int name_begin = 0;
2915     int name_end = 0;
2916     char save_ch = 0;
2917     JAM_RETURN_TYPE status = JAMC_SUCCESS;
2918     JAMS_SYMBOL_RECORD *symbol_record = NULL;
2919 
2920     if (urj_jam_version == 0)
2921         urj_jam_version = 2;
2922 
2923     if (urj_jam_version == 1)
2924         status = JAMC_SYNTAX_ERROR;
2925 
2926     if ((urj_jam_version == 2) &&
2927         (urj_jam_phase != JAM_PROCEDURE_PHASE) && (urj_jam_phase != JAM_DATA_PHASE))
2928     {
2929         status = JAMC_PHASE_ERROR;
2930     }
2931 
2932     if ((urj_jam_version == 2) && (urj_jam_phase == JAM_ACTION_PHASE))
2933     {
2934         status = JAMC_ACTION_NOT_FOUND;
2935     }
2936 
2937     if (status == JAMC_SUCCESS)
2938     {
2939         index = urj_jam_skip_instruction_name (statement_buffer);
2940 
2941         if (isalpha (statement_buffer[index]))
2942         {
2943             /*
2944              *      Get the data block name
2945              */
2946             name_begin = index;
2947             while ((jam_is_name_char (statement_buffer[index])) &&
2948                    (index < JAMC_MAX_STATEMENT_LENGTH))
2949             {
2950                 ++index;        /* skip over data block name */
2951             }
2952             name_end = index;
2953 
2954             save_ch = statement_buffer[name_end];
2955             statement_buffer[name_end] = JAMC_NULL_CHAR;
2956             status = urj_jam_add_symbol (JAM_DATA_BLOCK,
2957                                      &statement_buffer[name_begin], 0L,
2958                                      urj_jam_current_statement_position);
2959 
2960             /* get a pointer to the symbol record */
2961             if (status == JAMC_SUCCESS)
2962             {
2963                 status =
2964                     urj_jam_get_symbol_record (&statement_buffer[name_begin],
2965                                            &symbol_record);
2966             }
2967             statement_buffer[name_end] = save_ch;
2968 
2969             while ((isspace (statement_buffer[index])) &&
2970                    (index < JAMC_MAX_STATEMENT_LENGTH))
2971             {
2972                 ++index;        /* skip over white space */
2973             }
2974         }
2975         else
2976         {
2977             status = JAMC_SYNTAX_ERROR;
2978         }
2979 
2980         if ((status == JAMC_SUCCESS) &&
2981             (statement_buffer[index] != JAMC_SEMICOLON_CHAR))
2982         {
2983             status = JAMC_SYNTAX_ERROR;
2984         }
2985     }
2986 
2987     return status;
2988 }
2989 
2990 /****************************************************************************/
2991 /*                                                                          */
2992 
urj_jam_process_drscan_compare(char * statement_buffer,int32_t count_value,int32_t * in_data,int32_t in_index)2993 JAM_RETURN_TYPE urj_jam_process_drscan_compare
2994     (char *statement_buffer,
2995      int32_t count_value, int32_t *in_data, int32_t in_index)
2996 /*                                                                          */
2997 /*  Description:    Processes the arguments for the COMPARE version of the  */
2998 /*                  DRSCAN statement.  Calls urj_jam_swap_dr() to access the    */
2999 /*                  JTAG hardware interface.                                */
3000 /*                                                                          */
3001 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
3002 /*                                                                          */
3003 /****************************************************************************/
3004 {
3005 
3006 /* syntax: DRSCAN <length> [, <data>] [COMPARE <array>, <mask>, <result>] ; */
3007 
3008     int bit = 0;
3009     int index = 0;
3010     int expr_begin = 0;
3011     int expr_end = 0;
3012     int delimiter = 0;
3013     int actual = 0;
3014     int expected = 0;
3015     int mask = 0;
3016     int32_t comp_start_index = 0L;
3017     int32_t comp_stop_index = 0L;
3018     int32_t mask_start_index = 0L;
3019     int32_t mask_stop_index = 0L;
3020     int32_t start_index = 0;
3021     char save_ch = 0;
3022     int32_t *temp_array = NULL;
3023     BOOL result = true;
3024     JAMS_SYMBOL_RECORD *symbol_record = NULL;
3025     JAMS_HEAP_RECORD *heap_record = NULL;
3026     int32_t *comp_data = NULL;
3027     int32_t *mask_data = NULL;
3028     int32_t *literal_array_data = NULL;
3029     JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
3030 
3031     int32_t *tdi_data = NULL;
3032 
3033     if ((strncmp (statement_buffer, "CAPTURE", 7) == 0) &&
3034         (isspace (statement_buffer[7])))
3035     {
3036 
3037         int32_t stop_index;
3038 
3039         /* Next argument should be the capture array */
3040 
3041         statement_buffer += 8;
3042 
3043         status = urj_jam_find_argument (statement_buffer,
3044                                     &expr_begin, &expr_end, &delimiter);
3045 
3046         if (status == JAMC_SUCCESS)
3047         {
3048             save_ch = statement_buffer[expr_end];
3049             statement_buffer[expr_end] = JAMC_NULL_CHAR;
3050             status = urj_jam_get_array_argument (&statement_buffer[expr_begin],
3051                                              &symbol_record,
3052                                              &literal_array_data,
3053                                              &start_index, &stop_index, 1);
3054             statement_buffer[expr_end] = save_ch;
3055         }
3056 
3057         if ((status == JAMC_SUCCESS) && (literal_array_data != NULL))
3058         {
3059             /* literal array may not be used for capture buffer */
3060             status = JAMC_SYNTAX_ERROR;
3061         }
3062 
3063         if ((status == JAMC_SUCCESS) &&
3064             (stop_index != start_index + count_value - 1))
3065         {
3066             status = JAMC_BOUNDS_ERROR;
3067         }
3068 
3069         if (status == JAMC_SUCCESS)
3070         {
3071             if (symbol_record != NULL)
3072             {
3073                 heap_record = (JAMS_HEAP_RECORD *) symbol_record->value;
3074 
3075                 if (heap_record != NULL)
3076                 {
3077                     tdi_data = heap_record->data;
3078                 }
3079                 else
3080                 {
3081                     status = JAMC_INTERNAL_ERROR;
3082                 }
3083             }
3084             else
3085             {
3086                 status = JAMC_INTERNAL_ERROR;
3087             }
3088         }
3089 
3090         if (status == JAMC_SUCCESS)
3091         {
3092             if (statement_buffer[delimiter] == JAMC_SEMICOLON_CHAR)
3093             {
3094                 status = urj_jam_swap_dr (count_value, in_data, in_index,
3095                                       tdi_data, start_index);
3096                 return status;
3097             }
3098             else if (statement_buffer[delimiter] == JAMC_COMMA_CHAR)
3099             {
3100                 statement_buffer = statement_buffer + delimiter + 1;
3101             }
3102             else
3103             {
3104                 status = JAMC_SYNTAX_ERROR;
3105                 return status;
3106             }
3107         }
3108 
3109     }
3110 
3111     if ((strncmp (statement_buffer, "COMPARE", 7) == 0) &&
3112         (isspace (statement_buffer[7])))
3113     {
3114         statement_buffer += 8;
3115     }
3116     else
3117     {
3118         status = JAMC_SYNTAX_ERROR;
3119         return status;
3120     }
3121 
3122     /*
3123      *      Statement buffer should contain the part of the statement string
3124      *      after the COMPARE keyword.
3125      *
3126      *      The first argument should be the compare array.
3127      */
3128     status = urj_jam_find_argument (statement_buffer,
3129                                 &expr_begin, &expr_end, &delimiter);
3130 
3131     if ((status == JAMC_SUCCESS) &&
3132         (statement_buffer[delimiter] != JAMC_COMMA_CHAR))
3133     {
3134         status = JAMC_SYNTAX_ERROR;
3135     }
3136 
3137     if (status == JAMC_SUCCESS)
3138     {
3139         save_ch = statement_buffer[expr_end];
3140         statement_buffer[expr_end] = JAMC_NULL_CHAR;
3141         status = urj_jam_get_array_argument (&statement_buffer[expr_begin],
3142                                          &symbol_record, &literal_array_data,
3143                                          &comp_start_index, &comp_stop_index,
3144                                          1);
3145         statement_buffer[expr_end] = save_ch;
3146         index = delimiter + 1;
3147     }
3148 
3149     if ((status == JAMC_SUCCESS) &&
3150         (literal_array_data != NULL) &&
3151         (comp_start_index == 0) && (comp_stop_index > count_value - 1))
3152     {
3153         comp_stop_index = count_value - 1;
3154     }
3155 
3156     if ((status == JAMC_SUCCESS) &&
3157         (comp_stop_index != comp_start_index + count_value - 1))
3158     {
3159         status = JAMC_BOUNDS_ERROR;
3160     }
3161 
3162     if (status == JAMC_SUCCESS)
3163     {
3164         if (symbol_record != NULL)
3165         {
3166             heap_record = (JAMS_HEAP_RECORD *) symbol_record->value;
3167 
3168             if (heap_record != NULL)
3169             {
3170                 comp_data = heap_record->data;
3171             }
3172             else
3173             {
3174                 status = JAMC_INTERNAL_ERROR;
3175             }
3176         }
3177         else if (literal_array_data != NULL)
3178         {
3179             comp_data = literal_array_data;
3180         }
3181         else
3182         {
3183             status = JAMC_INTERNAL_ERROR;
3184         }
3185     }
3186 
3187     /*
3188      *      Find the next argument -- should be the mask array
3189      */
3190     if (status == JAMC_SUCCESS)
3191     {
3192         status = urj_jam_find_argument (&statement_buffer[index],
3193                                     &expr_begin, &expr_end, &delimiter);
3194 
3195         expr_begin += index;
3196         expr_end += index;
3197         delimiter += index;
3198     }
3199 
3200     if ((status == JAMC_SUCCESS) &&
3201         (statement_buffer[delimiter] != JAMC_COMMA_CHAR))
3202     {
3203         status = JAMC_SYNTAX_ERROR;
3204     }
3205 
3206     if (status == JAMC_SUCCESS)
3207     {
3208         save_ch = statement_buffer[expr_end];
3209         statement_buffer[expr_end] = JAMC_NULL_CHAR;
3210         status = urj_jam_get_array_argument (&statement_buffer[expr_begin],
3211                                          &symbol_record, &literal_array_data,
3212                                          &mask_start_index, &mask_stop_index,
3213                                          2);
3214         statement_buffer[expr_end] = save_ch;
3215         index = delimiter + 1;
3216     }
3217 
3218     if ((status == JAMC_SUCCESS) &&
3219         (literal_array_data != NULL) &&
3220         (mask_start_index == 0) && (mask_stop_index > count_value - 1))
3221     {
3222         mask_stop_index = count_value - 1;
3223     }
3224 
3225     if ((status == JAMC_SUCCESS) &&
3226         (mask_stop_index != mask_start_index + count_value - 1))
3227     {
3228         status = JAMC_BOUNDS_ERROR;
3229     }
3230 
3231     if (status == JAMC_SUCCESS)
3232     {
3233         if (symbol_record != NULL)
3234         {
3235             heap_record = (JAMS_HEAP_RECORD *) symbol_record->value;
3236 
3237             if (heap_record != NULL)
3238             {
3239                 mask_data = heap_record->data;
3240             }
3241             else
3242             {
3243                 status = JAMC_INTERNAL_ERROR;
3244             }
3245         }
3246         else if (literal_array_data != NULL)
3247         {
3248             mask_data = literal_array_data;
3249         }
3250         else
3251         {
3252             status = JAMC_INTERNAL_ERROR;
3253         }
3254     }
3255 
3256     /*
3257      *      Find the third argument -- should be the result variable
3258      */
3259     if (status == JAMC_SUCCESS)
3260     {
3261         status = urj_jam_find_argument (&statement_buffer[index],
3262                                     &expr_begin, &expr_end, &delimiter);
3263 
3264         expr_begin += index;
3265         expr_end += index;
3266         delimiter += index;
3267     }
3268 
3269     if ((status == JAMC_SUCCESS) &&
3270         (statement_buffer[delimiter] != JAMC_SEMICOLON_CHAR))
3271     {
3272         status = JAMC_SYNTAX_ERROR;
3273     }
3274 
3275     /*
3276      *      Result must be a scalar Boolean variable
3277      */
3278     if (status == JAMC_SUCCESS)
3279     {
3280         save_ch = statement_buffer[expr_end];
3281         statement_buffer[expr_end] = JAMC_NULL_CHAR;
3282         status = urj_jam_get_symbol_record (&statement_buffer[expr_begin],
3283                                         &symbol_record);
3284         statement_buffer[expr_end] = save_ch;
3285 
3286         if ((status == JAMC_SUCCESS) &&
3287             (symbol_record->type != JAM_BOOLEAN_SYMBOL))
3288         {
3289             status = JAMC_TYPE_MISMATCH;
3290         }
3291     }
3292 
3293     /*
3294      *      Find some free memory on the heap
3295      */
3296     if (status == JAMC_SUCCESS)
3297     {
3298         if (tdi_data != NULL)
3299         {
3300             temp_array = tdi_data;
3301         }
3302         else
3303         {
3304             temp_array = urj_jam_get_temp_workspace ((count_value >> 3) + 4);
3305 
3306             if (temp_array == NULL)
3307             {
3308                 status = JAMC_OUT_OF_MEMORY;
3309             }
3310             start_index = 0;
3311         }
3312     }
3313 
3314     /*
3315      *      Do the JTAG operation, saving the result in temp_array
3316      */
3317     if (status == JAMC_SUCCESS)
3318     {
3319         status = urj_jam_swap_dr (count_value, in_data, in_index, temp_array,
3320                               start_index);
3321     }
3322 
3323     /*
3324      *      Mask the data and do the comparison
3325      */
3326     if (status == JAMC_SUCCESS)
3327     {
3328         int32_t end_index = start_index + count_value;
3329         for (bit = start_index; (bit < end_index) && result; ++bit)
3330         {
3331             actual = temp_array[bit >> 5] & (1L << (bit & 0x1f)) ? 1 : 0;
3332             expected = comp_data[(bit + comp_start_index) >> 5]
3333                 & (1L << ((bit + comp_start_index) & 0x1f)) ? 1 : 0;
3334             mask = mask_data[(bit + mask_start_index) >> 5]
3335                 & (1L << ((bit + mask_start_index) & 0x1f)) ? 1 : 0;
3336 
3337             if ((actual & mask) != (expected & mask))
3338             {
3339                 result = false;
3340             }
3341         }
3342 
3343         symbol_record->value = result ? 1L : 0L;
3344     }
3345 
3346     if (tdi_data == NULL)
3347     {
3348         if (temp_array != NULL)
3349             urj_jam_free_temp_workspace (temp_array);
3350     }
3351 
3352     return status;
3353 }
3354 
3355 /****************************************************************************/
3356 /*                                                                          */
3357 
urj_jam_process_drscan_capture(char * statement_buffer,int32_t count_value,int32_t * in_data,int32_t in_index)3358 JAM_RETURN_TYPE urj_jam_process_drscan_capture
3359     (char *statement_buffer,
3360      int32_t count_value, int32_t *in_data, int32_t in_index)
3361 /*                                                                          */
3362 /*  Description:    Processes the arguments for the CAPTURE version of the  */
3363 /*                  DRSCAN statement.  Calls urj_jam_swap_dr() to access the    */
3364 /*                  JTAG hardware interface.                                */
3365 /*                                                                          */
3366 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
3367 /*                                                                          */
3368 /****************************************************************************/
3369 {
3370     /* syntax:  DRSCAN <length> [, <data>] [CAPTURE <array>] ; */
3371 
3372     int expr_begin = 0;
3373     int expr_end = 0;
3374     int delimiter = 0;
3375     int32_t start_index = 0L;
3376     int32_t stop_index = 0L;
3377     char save_ch = 0;
3378     int32_t *tdi_data = NULL;
3379     int32_t *literal_array_data = NULL;
3380     JAMS_SYMBOL_RECORD *symbol_record = NULL;
3381     JAMS_HEAP_RECORD *heap_record = NULL;
3382     JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
3383 
3384     /*
3385      *      Statement buffer should contain the part of the statement string
3386      *      after the CAPTURE keyword.
3387      *
3388      *      The only argument should be the capture array.
3389      */
3390     status = urj_jam_find_argument (statement_buffer,
3391                                 &expr_begin, &expr_end, &delimiter);
3392 
3393     if ((status == JAMC_SUCCESS) &&
3394         (statement_buffer[delimiter] != JAMC_SEMICOLON_CHAR))
3395     {
3396         status = JAMC_SYNTAX_ERROR;
3397     }
3398 
3399     if (status == JAMC_SUCCESS)
3400     {
3401         save_ch = statement_buffer[expr_end];
3402         statement_buffer[expr_end] = JAMC_NULL_CHAR;
3403         status = urj_jam_get_array_argument (&statement_buffer[expr_begin],
3404                                          &symbol_record, &literal_array_data,
3405                                          &start_index, &stop_index, 1);
3406         statement_buffer[expr_end] = save_ch;
3407     }
3408 
3409     if ((status == JAMC_SUCCESS) && (literal_array_data != NULL))
3410     {
3411         /* literal array may not be used for capture buffer */
3412         status = JAMC_SYNTAX_ERROR;
3413     }
3414 
3415     if ((status == JAMC_SUCCESS) &&
3416         (stop_index != start_index + count_value - 1))
3417     {
3418         status = JAMC_BOUNDS_ERROR;
3419     }
3420 
3421     if (status == JAMC_SUCCESS)
3422     {
3423         if (symbol_record != NULL)
3424         {
3425             heap_record = (JAMS_HEAP_RECORD *) symbol_record->value;
3426 
3427             if (heap_record != NULL)
3428             {
3429                 tdi_data = heap_record->data;
3430             }
3431             else
3432             {
3433                 status = JAMC_INTERNAL_ERROR;
3434             }
3435         }
3436         else
3437         {
3438             status = JAMC_INTERNAL_ERROR;
3439         }
3440     }
3441 
3442     /*
3443      *      Perform the JTAG operation, capturing data into the heap buffer
3444      */
3445     if (status == JAMC_SUCCESS)
3446     {
3447         status = urj_jam_swap_dr (count_value, in_data, in_index,
3448                               tdi_data, start_index);
3449     }
3450 
3451     return status;
3452 }
3453 
3454 /****************************************************************************/
3455 /*                                                                          */
3456 
3457 JAM_RETURN_TYPE
urj_jam_process_drscan(char * statement_buffer)3458 urj_jam_process_drscan (char *statement_buffer)
3459 /*                                                                          */
3460 /*  Description:    Processes DRSCAN statement, which shifts data through   */
3461 /*                  a data register of the JTAG interface                   */
3462 /*                                                                          */
3463 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
3464 /*                                                                          */
3465 /****************************************************************************/
3466 {
3467     /* syntax:  DRSCAN <length> [, <data>] [CAPTURE <array>] ; */
3468     /* or:  DRSCAN <length> [, <data>] [COMPARE <array>, <mask>, <result>] ; */
3469 
3470     int index = 0;
3471     int expr_begin = 0;
3472     int expr_end = 0;
3473     int delimiter = 0;
3474     int32_t count_value = 0L;
3475     int32_t start_index = 0L;
3476     int32_t stop_index = 0L;
3477     char save_ch = 0;
3478     int32_t *tdi_data = NULL;
3479     int32_t *literal_array_data = NULL;
3480     JAME_EXPRESSION_TYPE expr_type = JAM_ILLEGAL_EXPR_TYPE;
3481     JAMS_SYMBOL_RECORD *symbol_record = NULL;
3482     JAMS_HEAP_RECORD *heap_record = NULL;
3483     JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
3484 
3485     if ((urj_jam_version == 2) && (urj_jam_phase != JAM_PROCEDURE_PHASE))
3486     {
3487         return JAMC_PHASE_ERROR;
3488     }
3489 
3490     index = urj_jam_skip_instruction_name (statement_buffer);
3491 
3492     /* locate length */
3493     status = urj_jam_find_argument (&statement_buffer[index],
3494                                 &expr_begin, &expr_end, &delimiter);
3495 
3496     expr_begin += index;
3497     expr_end += index;
3498     delimiter += index;
3499 
3500     if ((status == JAMC_SUCCESS) &&
3501         (statement_buffer[delimiter] != JAMC_COMMA_CHAR))
3502     {
3503         status = JAMC_SYNTAX_ERROR;
3504     }
3505 
3506     if (status == JAMC_SUCCESS)
3507     {
3508         save_ch = statement_buffer[expr_end];
3509         statement_buffer[expr_end] = JAMC_NULL_CHAR;
3510         status =
3511             urj_jam_evaluate_expression (&statement_buffer[expr_begin],
3512                                      &count_value, &expr_type);
3513         statement_buffer[expr_end] = save_ch;
3514     }
3515 
3516     /*
3517      *      Check for integer expression
3518      */
3519     if ((status == JAMC_SUCCESS) &&
3520         (expr_type != JAM_INTEGER_EXPR) &&
3521         (expr_type != JAM_INT_OR_BOOL_EXPR))
3522     {
3523         status = JAMC_TYPE_MISMATCH;
3524     }
3525 
3526     /*
3527      *      Look for array variable with sub-range index
3528      */
3529     if (status == JAMC_SUCCESS)
3530     {
3531         index = delimiter + 1;
3532         status = urj_jam_find_argument (&statement_buffer[index],
3533                                     &expr_begin, &expr_end, &delimiter);
3534 
3535         expr_begin += index;
3536         expr_end += index;
3537         delimiter += index;
3538     }
3539 
3540     if ((status == JAMC_SUCCESS) &&
3541         (statement_buffer[delimiter] != JAMC_COMMA_CHAR) &&
3542         (statement_buffer[delimiter] != JAMC_SEMICOLON_CHAR))
3543     {
3544         status = JAMC_SYNTAX_ERROR;
3545     }
3546 
3547     if (status == JAMC_SUCCESS)
3548     {
3549         save_ch = statement_buffer[expr_end];
3550         statement_buffer[expr_end] = JAMC_NULL_CHAR;
3551         status = urj_jam_get_array_argument (&statement_buffer[expr_begin],
3552                                          &symbol_record, &literal_array_data,
3553                                          &start_index, &stop_index, 0);
3554         statement_buffer[expr_end] = save_ch;
3555     }
3556 
3557     if ((status == JAMC_SUCCESS) &&
3558         (literal_array_data != NULL) &&
3559         (start_index == 0) && (stop_index > count_value - 1))
3560     {
3561         stop_index = count_value - 1;
3562     }
3563 
3564     if (status == JAMC_SUCCESS)
3565     {
3566         if (symbol_record != NULL)
3567         {
3568             heap_record = (JAMS_HEAP_RECORD *) symbol_record->value;
3569 
3570             if (heap_record != NULL)
3571             {
3572                 tdi_data = heap_record->data;
3573             }
3574             else
3575             {
3576                 status = JAMC_INTERNAL_ERROR;
3577             }
3578         }
3579         else if (literal_array_data != NULL)
3580         {
3581             tdi_data = literal_array_data;
3582         }
3583         else
3584         {
3585             status = JAMC_INTERNAL_ERROR;
3586         }
3587     }
3588 
3589     if ((status == JAMC_SUCCESS) &&
3590         (statement_buffer[delimiter] == JAMC_SEMICOLON_CHAR))
3591     {
3592         /*
3593          *      Do a simple DRSCAN operation -- no capture or compare
3594          */
3595         status = urj_jam_do_drscan (count_value, tdi_data, start_index);
3596     }
3597     else if ((status == JAMC_SUCCESS) &&
3598              (statement_buffer[delimiter] == JAMC_COMMA_CHAR))
3599     {
3600         /*
3601          *      Delimiter was a COMMA, so look for CAPTURE or COMPARE keyword
3602          */
3603         index = delimiter + 1;
3604         while (isspace (statement_buffer[index]))
3605         {
3606             ++index;            /* skip over white space */
3607         }
3608 
3609         /*
3610          *      Do a DRSCAN with compare and or capture
3611          */
3612         status = urj_jam_process_drscan_compare (&statement_buffer[index],
3613                                              count_value, tdi_data,
3614                                              start_index);
3615     }
3616     else
3617     {
3618         status = JAMC_SYNTAX_ERROR;
3619     }
3620 
3621     return status;
3622 }
3623 
3624 /****************************************************************************/
3625 /*                                                                          */
3626 
3627 JAM_RETURN_TYPE
urj_jam_process_drstop(char * statement_buffer)3628 urj_jam_process_drstop (char *statement_buffer)
3629 /*                                                                          */
3630 /*  Description:    Sets stop-state for DR scan operations                  */
3631 /*                                                                          */
3632 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
3633 /*                                                                          */
3634 /****************************************************************************/
3635 {
3636     int index = 0;
3637     int expr_begin = 0;
3638     int expr_end = 0;
3639     int delimiter = 0;
3640     JAM_RETURN_TYPE status = JAMC_SUCCESS;
3641     JAME_JTAG_STATE state = JAM_ILLEGAL_JTAG_STATE;
3642 
3643     if ((urj_jam_version == 2) && (urj_jam_phase != JAM_PROCEDURE_PHASE))
3644     {
3645         return JAMC_PHASE_ERROR;
3646     }
3647 
3648     index = urj_jam_skip_instruction_name (statement_buffer);
3649 
3650     /*
3651      *      Get next argument
3652      */
3653     status = urj_jam_find_argument (&statement_buffer[index],
3654                                 &expr_begin, &expr_end, &delimiter);
3655 
3656     expr_begin += index;
3657     expr_end += index;
3658     delimiter += index;
3659 
3660     if ((status == JAMC_SUCCESS) &&
3661         (statement_buffer[delimiter] != JAMC_SEMICOLON_CHAR))
3662     {
3663         status = JAMC_SYNTAX_ERROR;
3664     }
3665 
3666     if (status == JAMC_SUCCESS)
3667     {
3668         statement_buffer[expr_end] = JAMC_NULL_CHAR;
3669         state = urj_jam_get_jtag_state_from_name (&statement_buffer[expr_begin]);
3670 
3671         if (state == JAM_ILLEGAL_JTAG_STATE)
3672         {
3673             status = JAMC_SYNTAX_ERROR;
3674         }
3675         else
3676         {
3677             /*
3678              *      Set DRSCAN stop state to the specified state
3679              */
3680             status = urj_jam_set_drstop_state (state);
3681         }
3682     }
3683 
3684     return status;
3685 }
3686 
3687 JAM_RETURN_TYPE
urj_jam_process_enddata(char * statement_buffer)3688 urj_jam_process_enddata (char *statement_buffer)
3689 {
3690     JAM_RETURN_TYPE status = JAMC_SUCCESS;
3691 
3692     if (urj_jam_version == 0)
3693         urj_jam_version = 2;
3694 
3695     if (urj_jam_version == 1)
3696         status = JAMC_SYNTAX_ERROR;
3697 
3698     if ((urj_jam_version == 2) && (urj_jam_phase != JAM_PROCEDURE_PHASE))
3699     {
3700         status = JAMC_PHASE_ERROR;
3701     }
3702 
3703     statement_buffer = statement_buffer;
3704 
3705     return status;
3706 }
3707 
3708 /****************************************************************************/
3709 /*                                                                          */
3710 
urj_jam_process_exit(char * statement_buffer,BOOL * done,int * exit_code)3711 JAM_RETURN_TYPE urj_jam_process_exit
3712     (char *statement_buffer, BOOL *done, int *exit_code)
3713 /*                                                                          */
3714 /*  Description:    This function terminates an JAM program.  The 'done'    */
3715 /*                  flag is set, halting program execution, and the         */
3716 /*                  exit_code value is set as specified in the statement.   */
3717 /*                                                                          */
3718 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
3719 /*                                                                          */
3720 /****************************************************************************/
3721 {
3722     int index = 0;
3723     int expr_begin = 0;
3724     int expr_end = 0;
3725     char save_ch = 0;
3726     int32_t exit_code_value = 0L;
3727     JAME_EXPRESSION_TYPE expr_type = JAM_ILLEGAL_EXPR_TYPE;
3728     JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
3729 
3730     if ((urj_jam_version == 2) && (urj_jam_phase != JAM_PROCEDURE_PHASE))
3731     {
3732         return JAMC_PHASE_ERROR;
3733     }
3734 
3735     index = urj_jam_skip_instruction_name (statement_buffer);
3736 
3737     /*
3738      *      Evaluate expression for exit code value
3739      */
3740     expr_begin = index;
3741     while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
3742            (index < JAMC_MAX_STATEMENT_LENGTH))
3743     {
3744         ++index;
3745     }
3746     while ((statement_buffer[index] != JAMC_SEMICOLON_CHAR) && (index > 0))
3747     {
3748         --index;
3749     }
3750     expr_end = index;
3751 
3752     if (expr_end > expr_begin)
3753     {
3754         save_ch = statement_buffer[expr_end];
3755         statement_buffer[expr_end] = JAMC_NULL_CHAR;
3756         status =
3757             urj_jam_evaluate_expression (&statement_buffer[expr_begin],
3758                                      &exit_code_value, &expr_type);
3759         statement_buffer[expr_end] = save_ch;
3760     }
3761 
3762     /*
3763      *      Check for integer expression
3764      */
3765     if ((status == JAMC_SUCCESS) &&
3766         (expr_type != JAM_INTEGER_EXPR) &&
3767         (expr_type != JAM_INT_OR_BOOL_EXPR))
3768     {
3769         status = JAMC_TYPE_MISMATCH;
3770     }
3771 
3772     /*
3773      *      Check range of exit code -- must be in range of signed 16-bit number
3774      *      (from -32767 to 32767) for compatibility with 16-bit systems.
3775      */
3776     if (((status == JAMC_SUCCESS) &&
3777          ((exit_code_value < -32767L))) || (exit_code_value > 32767L))
3778     {
3779         status = JAMC_INTEGER_OVERFLOW;
3780     }
3781 
3782     if (status == JAMC_SUCCESS)
3783     {
3784         /*
3785          *      Terminate the program
3786          */
3787         *done = true;
3788         *exit_code = (int) exit_code_value;
3789     }
3790 
3791     return status;
3792 }
3793 
3794 /****************************************************************************/
3795 /*                                                                          */
3796 
3797 JAM_RETURN_TYPE
urj_jam_process_export(char * statement_buffer)3798 urj_jam_process_export (char *statement_buffer)
3799 /*                                                                          */
3800 /*  Description:    Exports data outside the JAM interpreter (to the        */
3801 /*                  calling program)                                        */
3802 /*                                                                          */
3803 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
3804 /*                                                                          */
3805 /****************************************************************************/
3806 {
3807     int index = 0;
3808     int key_begin = 0;
3809     int key_end = 0;
3810     int expr_begin = 0;
3811     int expr_end = 0;
3812     int32_t value = 0L;
3813     JAME_EXPRESSION_TYPE expr_type = JAM_ILLEGAL_EXPR_TYPE;
3814     JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
3815 
3816     /* boolean array variables */
3817     char ba_save_ch = 0;
3818     int ba_expr_begin = 0;
3819     int ba_expr_end = 0;
3820     int32_t ba_start_index = 0L;
3821     int32_t ba_stop_index = 0L;
3822     int32_t *ba_literal_array_data = NULL;
3823     JAMS_SYMBOL_RECORD *ba_symbol_record = NULL;
3824     JAMS_HEAP_RECORD *ba_heap_record = NULL;
3825     unsigned char *ba_source_heap_data = NULL;
3826     /* end of boolean array variables */
3827 
3828     if ((urj_jam_version == 2) && (urj_jam_phase != JAM_PROCEDURE_PHASE))
3829     {
3830         return JAMC_PHASE_ERROR;
3831     }
3832 
3833     index = urj_jam_skip_instruction_name (statement_buffer);
3834 
3835     /*
3836      *      Find key string
3837      */
3838     key_begin = index;
3839     while (isspace (statement_buffer[index]) &&
3840            (index < JAMC_MAX_STATEMENT_LENGTH))
3841     {
3842         ++index;
3843     }
3844 
3845     /* the first argument must be a quoted string */
3846     if (statement_buffer[index] == JAMC_QUOTE_CHAR)
3847     {
3848         ++index;                /* step over quote char */
3849         key_begin = index;
3850 
3851         /* find matching quote */
3852         while ((statement_buffer[index] != JAMC_QUOTE_CHAR) &&
3853                (statement_buffer[index] != JAMC_NULL_CHAR) &&
3854                (index < JAMC_MAX_STATEMENT_LENGTH))
3855         {
3856             ++index;
3857         }
3858 
3859         if (statement_buffer[index] == JAMC_QUOTE_CHAR)
3860         {
3861             key_end = index;
3862             ++index;            /* step over quote char */
3863 
3864             while (isspace (statement_buffer[index]) &&
3865                    (index < JAMC_MAX_STATEMENT_LENGTH))
3866             {
3867                 ++index;
3868             }
3869 
3870             if (statement_buffer[index] == JAMC_COMMA_CHAR)
3871             {
3872                 ++index;        /* step over comma */
3873                 expr_begin = index;
3874 
3875                 /* check if it is a boolean array */
3876                 while (isspace (statement_buffer[index]) &&
3877                        (index < JAMC_MAX_STATEMENT_LENGTH))
3878                 {
3879                     ++index;
3880                 }
3881                 ba_expr_begin = index;
3882                 if (jam_is_name_char (statement_buffer[index]) &&
3883                     (index < JAMC_MAX_STATEMENT_LENGTH))
3884                 {
3885                     ++index;
3886                     while (jam_is_name_char (statement_buffer[index]) &&
3887                            (index < JAMC_MAX_STATEMENT_LENGTH))
3888                     {
3889                         ++index;
3890                     }
3891                     while (isspace (statement_buffer[index]) &&
3892                            (index < JAMC_MAX_STATEMENT_LENGTH))
3893                     {
3894                         ++index;
3895                     }
3896                     if (statement_buffer[index] == JAMC_LBRACKET_CHAR)
3897                     {
3898                         while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
3899                                (index < JAMC_MAX_STATEMENT_LENGTH))
3900                         {
3901                             ++index;
3902                         }
3903                         while ((statement_buffer[index] !=
3904                                 JAMC_SEMICOLON_CHAR) && (index > 0))
3905                         {
3906                             --index;
3907                         }
3908                         ba_expr_end = index;
3909                         ba_save_ch = statement_buffer[ba_expr_end];
3910                         statement_buffer[ba_expr_end] = JAMC_NULL_CHAR;
3911                         status =
3912                             urj_jam_get_array_argument (&statement_buffer
3913                                                     [ba_expr_begin],
3914                                                     &ba_symbol_record,
3915                                                     &ba_literal_array_data,
3916                                                     &ba_start_index,
3917                                                     &ba_stop_index, 0);
3918                         statement_buffer[ba_expr_end] = ba_save_ch;
3919 
3920                         if (status == JAMC_SUCCESS)
3921                         {
3922                             if (ba_symbol_record != NULL)
3923                             {
3924                                 if ((ba_symbol_record->type ==
3925                                      JAM_BOOLEAN_ARRAY_WRITABLE) ||
3926                                     (ba_symbol_record->type ==
3927                                      JAM_BOOLEAN_ARRAY_INITIALIZED))
3928                                 {
3929                                     ba_heap_record = (JAMS_HEAP_RECORD *)
3930                                         ba_symbol_record->value;
3931                                     if ((ba_start_index < 0L) ||
3932                                         (ba_start_index >=
3933                                          ba_heap_record->dimension)
3934                                         || (ba_stop_index < 0L)
3935                                         || (ba_stop_index >=
3936                                             ba_heap_record->dimension))
3937                                     {
3938                                         return JAMC_BOUNDS_ERROR;
3939                                     }
3940                                     ba_source_heap_data =
3941                                         (unsigned char *)
3942                                         ba_heap_record->data;
3943                                     statement_buffer[key_end] =
3944                                         JAMC_NULL_CHAR;
3945                                     urj_jam_export_boolean_array
3946                                         (&statement_buffer[key_begin],
3947                                          &ba_source_heap_data[ba_start_index],
3948                                          ba_stop_index - ba_start_index + 1L);
3949                                     return JAMC_SUCCESS;
3950                                 }
3951                                 else
3952                                     return JAMC_TYPE_MISMATCH;
3953                             }
3954                             else
3955                             {
3956                                 return JAMC_INTERNAL_ERROR;
3957                             }
3958                         }
3959                         else
3960                         {
3961                             return status;
3962                         }
3963                     }
3964                 }
3965                 /* end of boolean array check */
3966 
3967                 index = expr_begin;
3968                 while ((statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
3969                        (statement_buffer[index] != JAMC_NULL_CHAR) &&
3970                        (index < JAMC_MAX_STATEMENT_LENGTH))
3971                 {
3972                     ++index;
3973                 }
3974 
3975                 if (statement_buffer[index] == JAMC_SEMICOLON_CHAR)
3976                 {
3977                     expr_end = index;
3978                     statement_buffer[expr_end] = JAMC_NULL_CHAR;
3979                     status =
3980                         urj_jam_evaluate_expression (&statement_buffer
3981                                                  [expr_begin], &value,
3982                                                  &expr_type);
3983 
3984                     /*
3985                      *      May be integer or Boolean expression
3986                      */
3987                     if ((status == JAMC_SUCCESS) &&
3988                         (expr_type != JAM_INTEGER_EXPR) &&
3989                         (expr_type != JAM_BOOLEAN_EXPR) &&
3990                         (expr_type != JAM_INT_OR_BOOL_EXPR))
3991                     {
3992                         status = JAMC_TYPE_MISMATCH;
3993                     }
3994 
3995                     if (status == JAMC_SUCCESS)
3996                     {
3997                         /*
3998                          *      Export the key and value
3999                          */
4000                         statement_buffer[key_end] = JAMC_NULL_CHAR;
4001                         urj_jam_export_integer (&statement_buffer[key_begin],
4002                                             value);
4003                     }
4004                 }
4005             }
4006         }
4007     }
4008 
4009     return status;
4010 }
4011 
4012 /****************************************************************************/
4013 /*                                                                          */
4014 
4015 JAM_RETURN_TYPE
urj_jam_process_for(char * statement_buffer)4016 urj_jam_process_for (char *statement_buffer)
4017 /*                                                                          */
4018 /*  Description:    This function processes a FOR statement.  It creates a  */
4019 /*                  stack record and assigns the start value to the         */
4020 /*                  iterator variable                                       */
4021 /*                                                                          */
4022 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
4023 /*                                                                          */
4024 /****************************************************************************/
4025 {
4026     int index = 0;
4027     int variable_begin = 0;
4028     int variable_end = 0;
4029     int expr_begin = 0;
4030     int expr_end = 0;
4031     int32_t start_value = 0L;
4032     int32_t stop_value = 0L;
4033     int32_t step_value = 1L;
4034     char save_ch = 0;
4035     JAME_EXPRESSION_TYPE expr_type = JAM_ILLEGAL_EXPR_TYPE;
4036     JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
4037     JAMS_SYMBOL_RECORD *symbol_record = NULL;
4038 
4039     if ((urj_jam_version == 2) && (urj_jam_phase != JAM_PROCEDURE_PHASE))
4040     {
4041         return JAMC_PHASE_ERROR;
4042     }
4043 
4044     index = urj_jam_skip_instruction_name (statement_buffer);
4045 
4046     if (isalpha (statement_buffer[index]))
4047     {
4048         /* locate variable name */
4049         variable_begin = index;
4050         while ((jam_is_name_char (statement_buffer[index])) &&
4051                (index < JAMC_MAX_STATEMENT_LENGTH))
4052         {
4053             ++index;            /* skip over variable name */
4054         }
4055         variable_end = index;
4056 
4057         while ((isspace (statement_buffer[index])) &&
4058                (index < JAMC_MAX_STATEMENT_LENGTH))
4059         {
4060             ++index;            /* skip over white space */
4061         }
4062 
4063         if (statement_buffer[index] == JAMC_EQUAL_CHAR)
4064         {
4065             /*
4066              *      Get start value for loop
4067              */
4068             expr_begin = index + 1;
4069 
4070             expr_end = urj_jam_find_keyword (&statement_buffer[expr_begin], "TO");
4071 
4072             if (expr_end > 0)
4073             {
4074                 expr_end += expr_begin;
4075                 save_ch = statement_buffer[expr_end];
4076                 statement_buffer[expr_end] = JAMC_NULL_CHAR;
4077                 status =
4078                     urj_jam_evaluate_expression (&statement_buffer[expr_begin],
4079                                              &start_value, &expr_type);
4080                 statement_buffer[expr_end] = save_ch;
4081                 index = expr_end + 2;   /* step over "TO" */
4082             }
4083 
4084             /*
4085              *      Check for integer expression
4086              */
4087             if ((status == JAMC_SUCCESS) &&
4088                 (expr_type != JAM_INTEGER_EXPR) &&
4089                 (expr_type != JAM_INT_OR_BOOL_EXPR))
4090             {
4091                 status = JAMC_TYPE_MISMATCH;
4092             }
4093 
4094             if (status == JAMC_SUCCESS)
4095             {
4096                 /*
4097                  *      Get stop value for loop
4098                  */
4099                 while ((isspace (statement_buffer[index])) &&
4100                        (index < JAMC_MAX_STATEMENT_LENGTH))
4101                 {
4102                     ++index;    /* skip over white space */
4103                 }
4104 
4105                 expr_begin = index;
4106 
4107                 expr_end = urj_jam_find_keyword (&statement_buffer[expr_begin],
4108                                              "STEP");
4109 
4110                 status = JAMC_SYNTAX_ERROR;
4111                 if (expr_end > 0)
4112                 {
4113                     /* STEP found */
4114                     expr_end += expr_begin;
4115                     save_ch = statement_buffer[expr_end];
4116                     statement_buffer[expr_end] = JAMC_NULL_CHAR;
4117                     status =
4118                         urj_jam_evaluate_expression (&statement_buffer
4119                                                  [expr_begin], &stop_value,
4120                                                  &expr_type);
4121                     statement_buffer[expr_end] = save_ch;
4122                     index = expr_end + 4;       /* step over "STEP" */
4123 
4124                     /*
4125                      *      Check for integer expression
4126                      */
4127                     if ((status == JAMC_SUCCESS) &&
4128                         (expr_type != JAM_INTEGER_EXPR) &&
4129                         (expr_type != JAM_INT_OR_BOOL_EXPR))
4130                     {
4131                         status = JAMC_TYPE_MISMATCH;
4132                     }
4133 
4134                     if (status == JAMC_SUCCESS)
4135                     {
4136                         /*
4137                          *      Get step value
4138                          */
4139                         while ((isspace (statement_buffer[index])) &&
4140                                (index < JAMC_MAX_STATEMENT_LENGTH))
4141                         {
4142                             ++index;    /* skip over white space */
4143                         }
4144 
4145                         expr_begin = index;
4146                         expr_end = 0;
4147                         while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
4148                                (statement_buffer[index] !=
4149                                 JAMC_SEMICOLON_CHAR)
4150                                && (index < JAMC_MAX_STATEMENT_LENGTH))
4151                         {
4152                             ++index;
4153                         }
4154 
4155                         if ((statement_buffer[index] == JAMC_SEMICOLON_CHAR))
4156                         {
4157                             expr_end = index;
4158                         }
4159 
4160                         status = JAMC_SYNTAX_ERROR;
4161                         if (expr_end > expr_begin)
4162                         {
4163                             save_ch = statement_buffer[expr_end];
4164                             statement_buffer[expr_end] = JAMC_NULL_CHAR;
4165                             status =
4166                                 urj_jam_evaluate_expression (&statement_buffer
4167                                                          [expr_begin],
4168                                                          &step_value,
4169                                                          &expr_type);
4170                             statement_buffer[expr_end] = save_ch;
4171                         }
4172 
4173                         /* step value zero is illegal */
4174                         if ((status == JAMC_SUCCESS) && (step_value == 0))
4175                         {
4176                             status = JAMC_SYNTAX_ERROR;
4177                         }
4178 
4179                         /*
4180                          *      Check for integer expression
4181                          */
4182                         if ((status == JAMC_SUCCESS) &&
4183                             (expr_type != JAM_INTEGER_EXPR) &&
4184                             (expr_type != JAM_INT_OR_BOOL_EXPR))
4185                         {
4186                             status = JAMC_TYPE_MISMATCH;
4187                         }
4188                     }
4189                 }
4190                 else
4191                 {
4192                     /* STEP not found -- look for semicolon */
4193                     while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
4194                            (statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
4195                            (index < JAMC_MAX_STATEMENT_LENGTH))
4196                     {
4197                         ++index;
4198                     }
4199 
4200                     if (statement_buffer[index] == JAMC_SEMICOLON_CHAR)
4201                     {
4202                         expr_end = index;
4203                     }
4204 
4205                     /*
4206                      *      Get stop value for loop
4207                      */
4208                     status = JAMC_SYNTAX_ERROR;
4209                     if (expr_end > expr_begin)
4210                     {
4211                         save_ch = statement_buffer[expr_end];
4212                         statement_buffer[expr_end] = JAMC_NULL_CHAR;
4213                         status =
4214                             urj_jam_evaluate_expression (&statement_buffer
4215                                                      [expr_begin],
4216                                                      &stop_value, &expr_type);
4217                         statement_buffer[expr_end] = save_ch;
4218                     }
4219 
4220                     /*
4221                      *      Step value defaults to one
4222                      */
4223                     step_value = 1L;
4224 
4225                     /*
4226                      *      Check for integer expression
4227                      */
4228                     if ((status == JAMC_SUCCESS) &&
4229                         (expr_type != JAM_INTEGER_EXPR) &&
4230                         (expr_type != JAM_INT_OR_BOOL_EXPR))
4231                     {
4232                         status = JAMC_TYPE_MISMATCH;
4233                     }
4234                 }
4235             }
4236         }
4237     }
4238 
4239     /*
4240      *      We have extracted the variable name and the start, stop, and
4241      *      step values from the statement buffer.  Now set the variable
4242      *      to the start value and push a stack record onto the stack.
4243      */
4244     if (status == JAMC_SUCCESS)
4245     {
4246         /*
4247          *      Find the variable (must be an integer)
4248          */
4249         status = JAMC_SYNTAX_ERROR;
4250         save_ch = statement_buffer[variable_end];
4251         statement_buffer[variable_end] = JAMC_NULL_CHAR;
4252         status = urj_jam_get_symbol_record (&statement_buffer[variable_begin],
4253                                         &symbol_record);
4254 
4255         if ((status == JAMC_SUCCESS) &&
4256             (symbol_record->type != JAM_INTEGER_SYMBOL))
4257         {
4258             status = JAMC_TYPE_MISMATCH;
4259         }
4260 
4261         if (status == JAMC_SUCCESS)
4262         {
4263             /*
4264              *      Set the variable to the start value
4265              */
4266             status = urj_jam_set_symbol_value (JAM_INTEGER_SYMBOL,
4267                                            &statement_buffer[variable_begin],
4268                                            start_value);
4269         }
4270         statement_buffer[variable_end] = save_ch;
4271     }
4272 
4273     if (status == JAMC_SUCCESS)
4274     {
4275         /*
4276          *      Push a record onto the stack
4277          */
4278         status = urj_jam_push_fornext_record (symbol_record,
4279                                           urj_jam_next_statement_position,
4280                                           stop_value, step_value);
4281     }
4282 
4283     return status;
4284 }
4285 
4286 /****************************************************************************/
4287 /*                                                                          */
4288 
4289 JAM_RETURN_TYPE
urj_jam_process_frequency(char * statement_buffer)4290 urj_jam_process_frequency (char *statement_buffer)
4291 /*                                                                          */
4292 /*  Description:    This function processes a FREQUENCY statement.  If the  */
4293 /*                  specified frequency (in cycles per second) is less than */
4294 /*                  the expected frequency of an ISA parallel port about    */
4295 /*                  (200 KHz) then delays will be added to each clock cycle.*/
4296 /*                                                                          */
4297 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
4298 /*                                                                          */
4299 /****************************************************************************/
4300 {
4301     int index = 0;
4302     int ret = 0;
4303     int expr_begin = 0;
4304     int expr_end = 0;
4305     int32_t expr_value = 0L;
4306     char save_ch = 0;
4307     JAME_EXPRESSION_TYPE expr_type = JAM_ILLEGAL_EXPR_TYPE;
4308     JAM_RETURN_TYPE status = JAMC_SUCCESS;
4309 
4310     if (urj_jam_version == 0)
4311         urj_jam_version = 2;
4312 
4313     if (urj_jam_version != 2)
4314         status = JAMC_SYNTAX_ERROR;
4315 
4316     if ((urj_jam_version == 2) && (urj_jam_phase != JAM_PROCEDURE_PHASE))
4317     {
4318         status = JAMC_PHASE_ERROR;
4319     }
4320 
4321     if (status == JAMC_SUCCESS)
4322     {
4323         index = urj_jam_skip_instruction_name (statement_buffer);
4324 
4325         while (isspace (statement_buffer[index]) &&
4326                (index < JAMC_MAX_STATEMENT_LENGTH))
4327         {
4328             ++index;
4329         }
4330 
4331         expr_begin = index;
4332 
4333         while ((statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
4334                (index < JAMC_MAX_STATEMENT_LENGTH))
4335         {
4336             ++index;
4337         }
4338 
4339         expr_end = index;
4340 
4341         if (statement_buffer[index] == JAMC_SEMICOLON_CHAR)
4342         {
4343             if (expr_end > expr_begin)
4344             {
4345                 save_ch = statement_buffer[expr_end];
4346                 statement_buffer[expr_end] = JAMC_NULL_CHAR;
4347                 status =
4348                     urj_jam_evaluate_expression (&statement_buffer[expr_begin],
4349                                              &expr_value, &expr_type);
4350                 statement_buffer[expr_end] = save_ch;
4351 
4352                 if (status == JAMC_SUCCESS)
4353                 {
4354                     //ret = jam_set_frequency (expr_value);
4355                 }
4356             }
4357             else
4358             {
4359                 //ret = jam_set_frequency (-1L);  /* set default frequency */
4360             }
4361         }
4362         else
4363         {
4364             /* semicolon not found */
4365             status = JAMC_SYNTAX_ERROR;
4366         }
4367 
4368         if ((status == JAMC_SUCCESS) && (ret != 0))
4369         {
4370             /* return code from jam_set_frequency() indicates an error */
4371             status = JAMC_BOUNDS_ERROR;
4372         }
4373     }
4374 
4375     return status;
4376 }
4377 
4378 /****************************************************************************/
4379 /*                                                                          */
4380 
urj_jam_process_if(char * statement_buffer,BOOL * reuse_statement_buffer)4381 JAM_RETURN_TYPE urj_jam_process_if
4382     (char *statement_buffer, BOOL *reuse_statement_buffer)
4383 /*                                                                          */
4384 /*  Description:    Processes an IF (conditional) statement.  If the        */
4385 /*                  condition is true, then the input stream pointer is     */
4386 /*                  set to the position of the statement to be executed     */
4387 /*                  (whatever follows the THEN keyword) which will be       */
4388 /*                  fetched normally and processed as the next statement.   */
4389 /*                                                                          */
4390 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
4391 /*                                                                          */
4392 /****************************************************************************/
4393 {
4394     int index = 0;
4395     int expr_begin = 0;
4396     int expr_end = 0;
4397     int32_t conditional_value = 0L;
4398     int then_index = 0L;
4399     char save_ch = 0;
4400     JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
4401     JAME_EXPRESSION_TYPE expr_type = JAM_ILLEGAL_EXPR_TYPE;
4402 
4403     if ((urj_jam_version == 2) && (urj_jam_phase != JAM_PROCEDURE_PHASE))
4404     {
4405         return JAMC_PHASE_ERROR;
4406     }
4407 
4408     index = urj_jam_skip_instruction_name (statement_buffer);
4409 
4410     /*
4411      *      Evaluate conditional expression
4412      */
4413     expr_begin = index;
4414     then_index = urj_jam_find_keyword (&statement_buffer[expr_begin], "THEN");
4415 
4416     if (then_index > 0)
4417     {
4418         expr_end = expr_begin + then_index;
4419 
4420         if (expr_end > expr_begin)
4421         {
4422             save_ch = statement_buffer[expr_end];
4423             statement_buffer[expr_end] = JAMC_NULL_CHAR;
4424             status =
4425                 urj_jam_evaluate_expression (&statement_buffer[expr_begin],
4426                                          &conditional_value, &expr_type);
4427             statement_buffer[expr_end] = save_ch;
4428         }
4429 
4430         /*
4431          *      Check for Boolean expression
4432          */
4433         if ((status == JAMC_SUCCESS) &&
4434             (expr_type != JAM_BOOLEAN_EXPR) &&
4435             (expr_type != JAM_INT_OR_BOOL_EXPR))
4436         {
4437             status = JAMC_TYPE_MISMATCH;
4438         }
4439 
4440         if (status == JAMC_SUCCESS)
4441         {
4442             if (conditional_value)
4443             {
4444                 index = expr_end + 4;
4445                 while ((isspace (statement_buffer[index])) &&
4446                        (index < JAMC_MAX_STATEMENT_LENGTH))
4447                 {
4448                     ++index;    /* skip over white space */
4449                 }
4450 
4451                 /*
4452                  *      Copy whatever appears after "THEN" to beginning of buffer
4453                  *      so it can be reused.
4454                  */
4455                 strcpy (statement_buffer, &statement_buffer[index]);
4456                 *reuse_statement_buffer = true;
4457             }
4458             /*
4459              *      (else do nothing if conditional value is false)
4460              */
4461         }
4462     }
4463 
4464     return status;
4465 }
4466 
4467 /****************************************************************************/
4468 /*                                                                          */
4469 
4470 JAM_RETURN_TYPE
urj_jam_process_integer(char * statement_buffer)4471 urj_jam_process_integer (char *statement_buffer)
4472 /*                                                                          */
4473 /*  Description:    Processes a INTEGER variable declaration statement      */
4474 /*                                                                          */
4475 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
4476 /*                                                                          */
4477 /****************************************************************************/
4478 {
4479     int index = 0;
4480     int variable_begin = 0;
4481     int variable_end = 0;
4482     int dim_begin = 0;
4483     int dim_end = 0;
4484     int expr_begin = 0;
4485     int expr_end = 0;
4486     int32_t dim_value = 0L;
4487     int32_t init_value = 0L;
4488     char save_ch = 0;
4489     JAME_EXPRESSION_TYPE expr_type = JAM_ILLEGAL_EXPR_TYPE;
4490     JAMS_SYMBOL_RECORD *symbol_record = NULL;
4491     JAMS_HEAP_RECORD *heap_record = NULL;
4492     JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
4493 
4494     if ((urj_jam_version == 2) &&
4495         (urj_jam_phase != JAM_PROCEDURE_PHASE) && (urj_jam_phase != JAM_DATA_PHASE))
4496     {
4497         return JAMC_PHASE_ERROR;
4498     }
4499 
4500     index = urj_jam_skip_instruction_name (statement_buffer);
4501 
4502     if (isalpha (statement_buffer[index]))
4503     {
4504         /* locate variable name */
4505         variable_begin = index;
4506         while ((jam_is_name_char (statement_buffer[index])) &&
4507                (index < JAMC_MAX_STATEMENT_LENGTH))
4508         {
4509             ++index;            /* skip over variable name */
4510         }
4511         variable_end = index;
4512 
4513         while ((isspace (statement_buffer[index])) &&
4514                (index < JAMC_MAX_STATEMENT_LENGTH))
4515         {
4516             ++index;            /* skip over white space */
4517         }
4518 
4519         if (statement_buffer[index] == JAMC_LBRACKET_CHAR)
4520         {
4521             /*
4522              *      Array declaration
4523              */
4524             dim_begin = index + 1;
4525             while ((statement_buffer[index] != JAMC_RBRACKET_CHAR) &&
4526                    (index < JAMC_MAX_STATEMENT_LENGTH))
4527             {
4528                 ++index;        /* find matching bracket */
4529             }
4530             if (statement_buffer[index] == JAMC_RBRACKET_CHAR)
4531             {
4532                 dim_end = index;
4533                 ++index;
4534             }
4535             while ((isspace (statement_buffer[index])) &&
4536                    (index < JAMC_MAX_STATEMENT_LENGTH))
4537             {
4538                 ++index;        /* skip over white space */
4539             }
4540 
4541             if (dim_end > dim_begin)
4542             {
4543                 save_ch = statement_buffer[dim_end];
4544                 statement_buffer[dim_end] = JAMC_NULL_CHAR;
4545                 status =
4546                     urj_jam_evaluate_expression (&statement_buffer[dim_begin],
4547                                              &dim_value, &expr_type);
4548                 statement_buffer[dim_end] = save_ch;
4549             }
4550 
4551             /*
4552              *      Check for integer expression
4553              */
4554             if ((status == JAMC_SUCCESS) &&
4555                 (expr_type != JAM_INTEGER_EXPR) &&
4556                 (expr_type != JAM_INT_OR_BOOL_EXPR))
4557             {
4558                 status = JAMC_TYPE_MISMATCH;
4559             }
4560 
4561             if (status == JAMC_SUCCESS)
4562             {
4563                 /*
4564                  *      Add the array name to the symbol table
4565                  */
4566                 save_ch = statement_buffer[variable_end];
4567                 statement_buffer[variable_end] = JAMC_NULL_CHAR;
4568                 status = urj_jam_add_symbol (JAM_INTEGER_ARRAY_WRITABLE,
4569                                          &statement_buffer[variable_begin],
4570                                          0L, urj_jam_current_statement_position);
4571 
4572                 /* get a pointer to the symbol record */
4573                 if (status == JAMC_SUCCESS)
4574                 {
4575                     status =
4576                         urj_jam_get_symbol_record (&statement_buffer
4577                                                [variable_begin],
4578                                                &symbol_record);
4579                 }
4580                 statement_buffer[variable_end] = save_ch;
4581             }
4582 
4583             if ((status == JAMC_SUCCESS) &&
4584                 (symbol_record->type == JAM_INTEGER_ARRAY_WRITABLE) &&
4585                 (symbol_record->value == 0))
4586             {
4587                 if (statement_buffer[index] == JAMC_EQUAL_CHAR)
4588                 {
4589                     /*
4590                      *      Array has initialization data:  read it in.
4591                      */
4592                     status = urj_jam_add_heap_record (symbol_record, &heap_record,
4593                                                   dim_value);
4594 
4595                     if (status == JAMC_SUCCESS)
4596                     {
4597                         symbol_record->value = (int32_t) heap_record;
4598 
4599                         status = urj_jam_read_integer_array_data (heap_record,
4600                                                               &statement_buffer
4601                                                               [index + 1]);
4602                     }
4603                 }
4604                 else if (statement_buffer[index] == JAMC_SEMICOLON_CHAR)
4605                 {
4606                     /*
4607                      *      Array has no initialization data.
4608                      *      Allocate a buffer on the heap:
4609                      */
4610                     status = urj_jam_add_heap_record (symbol_record, &heap_record,
4611                                                   dim_value);
4612 
4613                     if (status == JAMC_SUCCESS)
4614                     {
4615                         symbol_record->value = (int32_t) heap_record;
4616                     }
4617                 }
4618             }
4619             else
4620             {
4621                 /* this should be end of the statement */
4622                 if (status == JAMC_SUCCESS)
4623                     status = JAMC_SYNTAX_ERROR;
4624             }
4625         }
4626         else
4627         {
4628             /*
4629              *      Scalar variable declaration
4630              */
4631             if (statement_buffer[index] == JAMC_SEMICOLON_CHAR)
4632             {
4633                 status = JAMC_SUCCESS;
4634             }
4635             else if (statement_buffer[index] == JAMC_EQUAL_CHAR)
4636             {
4637                 /*
4638                  *      Evaluate initialization expression
4639                  */
4640                 expr_begin = index + 1;
4641                 while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
4642                        (index < JAMC_MAX_STATEMENT_LENGTH))
4643                 {
4644                     ++index;
4645                 }
4646                 while ((statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
4647                        (index > 0))
4648                 {
4649                     --index;
4650                 }
4651                 expr_end = index;
4652 
4653                 if (expr_end > expr_begin)
4654                 {
4655                     save_ch = statement_buffer[expr_end];
4656                     statement_buffer[expr_end] = JAMC_NULL_CHAR;
4657                     status =
4658                         urj_jam_evaluate_expression (&statement_buffer
4659                                                  [expr_begin], &init_value,
4660                                                  &expr_type);
4661                     statement_buffer[expr_end] = save_ch;
4662                 }
4663 
4664                 /*
4665                  *      Check for integer expression
4666                  */
4667                 if ((status == JAMC_SUCCESS) &&
4668                     (expr_type != JAM_INTEGER_EXPR) &&
4669                     (expr_type != JAM_INT_OR_BOOL_EXPR))
4670                 {
4671                     status = JAMC_TYPE_MISMATCH;
4672                 }
4673             }
4674 
4675             if (status == JAMC_SUCCESS)
4676             {
4677                 /*
4678                  *      Add the variable name to the symbol table
4679                  */
4680                 save_ch = statement_buffer[variable_end];
4681                 statement_buffer[variable_end] = JAMC_NULL_CHAR;
4682                 status = urj_jam_add_symbol (JAM_INTEGER_SYMBOL,
4683                                          &statement_buffer[variable_begin],
4684                                          init_value,
4685                                          urj_jam_current_statement_position);
4686                 statement_buffer[variable_end] = save_ch;
4687             }
4688         }
4689     }
4690 
4691     return status;
4692 }
4693 
4694 /****************************************************************************/
4695 /*                                                                          */
4696 
urj_jam_process_irscan_compare(char * statement_buffer,int32_t count_value,int32_t * in_data,int32_t in_index)4697 JAM_RETURN_TYPE urj_jam_process_irscan_compare
4698     (char *statement_buffer,
4699      int32_t count_value, int32_t *in_data, int32_t in_index)
4700 /*                                                                          */
4701 /*  Description:    Processes the arguments for the COMPARE version of the  */
4702 /*                  IRSCAN statement.  Calls urj_jam_swap_ir() to access the    */
4703 /*                  JTAG hardware interface.                                */
4704 /*                                                                          */
4705 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
4706 /*                                                                          */
4707 /****************************************************************************/
4708 {
4709 
4710 /* syntax: IRSCAN <length> [, <data>] [COMPARE <array>, <mask>, <result>] ; */
4711 
4712     int bit = 0;
4713     int index = 0;
4714     int expr_begin = 0;
4715     int expr_end = 0;
4716     int delimiter = 0;
4717     int actual = 0;
4718     int expected = 0;
4719     int mask = 0;
4720     int32_t comp_start_index = 0L;
4721     int32_t comp_stop_index = 0L;
4722     int32_t mask_start_index = 0L;
4723     int32_t mask_stop_index = 0L;
4724     char save_ch = 0;
4725     int32_t *temp_array = NULL;
4726     BOOL result = true;
4727     JAMS_SYMBOL_RECORD *symbol_record = NULL;
4728     JAMS_HEAP_RECORD *heap_record = NULL;
4729     int32_t *comp_data = NULL;
4730     int32_t *mask_data = NULL;
4731     int32_t *literal_array_data = NULL;
4732     JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
4733 
4734     /*
4735      *      Statement buffer should contain the part of the statement string
4736      *      after the COMPARE keyword.
4737      *
4738      *      The first argument should be the compare array.
4739      */
4740     status = urj_jam_find_argument (statement_buffer,
4741                                 &expr_begin, &expr_end, &delimiter);
4742 
4743     if ((status == JAMC_SUCCESS) &&
4744         (statement_buffer[delimiter] != JAMC_COMMA_CHAR))
4745     {
4746         status = JAMC_SYNTAX_ERROR;
4747     }
4748 
4749     if (status == JAMC_SUCCESS)
4750     {
4751         save_ch = statement_buffer[expr_end];
4752         statement_buffer[expr_end] = JAMC_NULL_CHAR;
4753         status = urj_jam_get_array_argument (&statement_buffer[expr_begin],
4754                                          &symbol_record, &literal_array_data,
4755                                          &comp_start_index, &comp_stop_index,
4756                                          1);
4757         statement_buffer[expr_end] = save_ch;
4758         index = delimiter + 1;
4759     }
4760 
4761     if ((status == JAMC_SUCCESS) &&
4762         (literal_array_data != NULL) &&
4763         (comp_start_index == 0) && (comp_stop_index > count_value - 1))
4764     {
4765         comp_stop_index = count_value - 1;
4766     }
4767 
4768     if ((status == JAMC_SUCCESS) &&
4769         (comp_stop_index != comp_start_index + count_value - 1))
4770     {
4771         status = JAMC_BOUNDS_ERROR;
4772     }
4773 
4774     if (status == JAMC_SUCCESS)
4775     {
4776         if (symbol_record != NULL)
4777         {
4778             heap_record = (JAMS_HEAP_RECORD *) symbol_record->value;
4779 
4780             if (heap_record != NULL)
4781             {
4782                 comp_data = heap_record->data;
4783             }
4784             else
4785             {
4786                 status = JAMC_INTERNAL_ERROR;
4787             }
4788         }
4789         else if (literal_array_data != NULL)
4790         {
4791             comp_data = literal_array_data;
4792         }
4793         else
4794         {
4795             status = JAMC_INTERNAL_ERROR;
4796         }
4797     }
4798 
4799     /*
4800      *      Find the next argument -- should be the mask array
4801      */
4802     if (status == JAMC_SUCCESS)
4803     {
4804         status = urj_jam_find_argument (&statement_buffer[index],
4805                                     &expr_begin, &expr_end, &delimiter);
4806 
4807         expr_begin += index;
4808         expr_end += index;
4809         delimiter += index;
4810     }
4811 
4812     if ((status == JAMC_SUCCESS) &&
4813         (statement_buffer[delimiter] != JAMC_COMMA_CHAR))
4814     {
4815         status = JAMC_SYNTAX_ERROR;
4816     }
4817 
4818     if (status == JAMC_SUCCESS)
4819     {
4820         save_ch = statement_buffer[expr_end];
4821         statement_buffer[expr_end] = JAMC_NULL_CHAR;
4822         status = urj_jam_get_array_argument (&statement_buffer[expr_begin],
4823                                          &symbol_record, &literal_array_data,
4824                                          &mask_start_index, &mask_stop_index,
4825                                          2);
4826         statement_buffer[expr_end] = save_ch;
4827         index = delimiter + 1;
4828     }
4829 
4830     if ((status == JAMC_SUCCESS) &&
4831         (literal_array_data != NULL) &&
4832         (mask_start_index == 0) && (mask_stop_index > count_value - 1))
4833     {
4834         mask_stop_index = count_value - 1;
4835     }
4836 
4837     if ((status == JAMC_SUCCESS) &&
4838         (mask_stop_index != mask_start_index + count_value - 1))
4839     {
4840         status = JAMC_BOUNDS_ERROR;
4841     }
4842 
4843     if (status == JAMC_SUCCESS)
4844     {
4845         if (symbol_record != NULL)
4846         {
4847             heap_record = (JAMS_HEAP_RECORD *) symbol_record->value;
4848 
4849             if (heap_record != NULL)
4850             {
4851                 mask_data = heap_record->data;
4852             }
4853             else
4854             {
4855                 status = JAMC_INTERNAL_ERROR;
4856             }
4857         }
4858         else if (literal_array_data != NULL)
4859         {
4860             mask_data = literal_array_data;
4861         }
4862         else
4863         {
4864             status = JAMC_INTERNAL_ERROR;
4865         }
4866     }
4867 
4868     /*
4869      *      Find the third argument -- should be the result variable
4870      */
4871     if (status == JAMC_SUCCESS)
4872     {
4873         status = urj_jam_find_argument (&statement_buffer[index],
4874                                     &expr_begin, &expr_end, &delimiter);
4875 
4876         expr_begin += index;
4877         expr_end += index;
4878         delimiter += index;
4879     }
4880 
4881     if ((status == JAMC_SUCCESS) &&
4882         (statement_buffer[delimiter] != JAMC_SEMICOLON_CHAR))
4883     {
4884         status = JAMC_SYNTAX_ERROR;
4885     }
4886 
4887     /*
4888      *      Result must be a scalar Boolean variable
4889      */
4890     if (status == JAMC_SUCCESS)
4891     {
4892         save_ch = statement_buffer[expr_end];
4893         statement_buffer[expr_end] = JAMC_NULL_CHAR;
4894         status = urj_jam_get_symbol_record (&statement_buffer[expr_begin],
4895                                         &symbol_record);
4896         statement_buffer[expr_end] = save_ch;
4897 
4898         if ((status == JAMC_SUCCESS) &&
4899             (symbol_record->type != JAM_BOOLEAN_SYMBOL))
4900         {
4901             status = JAMC_TYPE_MISMATCH;
4902         }
4903     }
4904 
4905     /*
4906      *      Find some free memory on the heap
4907      */
4908     if (status == JAMC_SUCCESS)
4909     {
4910         temp_array = urj_jam_get_temp_workspace ((count_value >> 3) + 4);
4911 
4912         if (temp_array == NULL)
4913         {
4914             status = JAMC_OUT_OF_MEMORY;
4915         }
4916     }
4917 
4918     /*
4919      *      Do the JTAG operation, saving the result in temp_array
4920      */
4921     if (status == JAMC_SUCCESS)
4922     {
4923         status = urj_jam_swap_ir (count_value, in_data, in_index, temp_array, 0);
4924     }
4925 
4926     /*
4927      *      Mask the data and do the comparison
4928      */
4929     if (status == JAMC_SUCCESS)
4930     {
4931         for (bit = 0; (bit < count_value) && result; ++bit)
4932         {
4933             actual = temp_array[bit >> 5] & (1L << (bit & 0x1f)) ? 1 : 0;
4934             expected = comp_data[(bit + comp_start_index) >> 5]
4935                 & (1L << ((bit + comp_start_index) & 0x1f)) ? 1 : 0;
4936             mask = mask_data[(bit + mask_start_index) >> 5]
4937                 & (1L << ((bit + mask_start_index) & 0x1f)) ? 1 : 0;
4938 
4939             if ((actual & mask) != (expected & mask))
4940             {
4941                 result = false;
4942             }
4943         }
4944 
4945         symbol_record->value = result ? 1L : 0L;
4946     }
4947 
4948     if (temp_array != NULL)
4949         urj_jam_free_temp_workspace (temp_array);
4950 
4951     return status;
4952 }
4953 
4954 /****************************************************************************/
4955 /*                                                                          */
4956 
urj_jam_process_irscan_capture(char * statement_buffer,int32_t count_value,int32_t * in_data,int32_t in_index)4957 JAM_RETURN_TYPE urj_jam_process_irscan_capture
4958     (char *statement_buffer,
4959      int32_t count_value, int32_t *in_data, int32_t in_index)
4960 /*                                                                          */
4961 /*  Description:    Processes the arguments for the CAPTURE version of the  */
4962 /*                  IRSCAN statement.  Calls urj_jam_swap_ir() to access the    */
4963 /*                  JTAG hardware interface.                                */
4964 /*                                                                          */
4965 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
4966 /*                                                                          */
4967 /****************************************************************************/
4968 {
4969     /* syntax:  IRSCAN <length> [, <data>] [CAPTURE <array>] ; */
4970 
4971     int expr_begin = 0;
4972     int expr_end = 0;
4973     int delimiter = 0;
4974     int32_t start_index = 0L;
4975     int32_t stop_index = 0L;
4976     char save_ch = 0;
4977     int32_t *tdi_data = NULL;
4978     int32_t *literal_array_data = NULL;
4979     JAMS_SYMBOL_RECORD *symbol_record = NULL;
4980     JAMS_HEAP_RECORD *heap_record = NULL;
4981     JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
4982 
4983     /*
4984      *      Statement buffer should contain the part of the statement string
4985      *      after the CAPTURE keyword.
4986      *
4987      *      The only argument should be the capture array.
4988      */
4989     status = urj_jam_find_argument (statement_buffer,
4990                                 &expr_begin, &expr_end, &delimiter);
4991 
4992     if ((status == JAMC_SUCCESS) &&
4993         (statement_buffer[delimiter] != JAMC_SEMICOLON_CHAR))
4994     {
4995         status = JAMC_SYNTAX_ERROR;
4996     }
4997 
4998     if (status == JAMC_SUCCESS)
4999     {
5000         save_ch = statement_buffer[expr_end];
5001         statement_buffer[expr_end] = JAMC_NULL_CHAR;
5002         status = urj_jam_get_array_argument (&statement_buffer[expr_begin],
5003                                          &symbol_record, &literal_array_data,
5004                                          &start_index, &stop_index, 1);
5005         statement_buffer[expr_end] = save_ch;
5006     }
5007 
5008     if ((status == JAMC_SUCCESS) && (literal_array_data != NULL))
5009     {
5010         /* literal array may not be used for capture buffer */
5011         status = JAMC_SYNTAX_ERROR;
5012     }
5013 
5014     if ((status == JAMC_SUCCESS) &&
5015         (stop_index != start_index + count_value - 1))
5016     {
5017         status = JAMC_BOUNDS_ERROR;
5018     }
5019 
5020     if (status == JAMC_SUCCESS)
5021     {
5022         if (symbol_record != NULL)
5023         {
5024             heap_record = (JAMS_HEAP_RECORD *) symbol_record->value;
5025 
5026             if (heap_record != NULL)
5027             {
5028                 tdi_data = heap_record->data;
5029             }
5030             else
5031             {
5032                 status = JAMC_INTERNAL_ERROR;
5033             }
5034         }
5035         else
5036         {
5037             status = JAMC_INTERNAL_ERROR;
5038         }
5039     }
5040 
5041     /*
5042      *      Perform the JTAG operation, capturing data into the heap buffer
5043      */
5044     if (status == JAMC_SUCCESS)
5045     {
5046         status = urj_jam_swap_ir (count_value, in_data, in_index,
5047                               tdi_data, start_index);
5048     }
5049 
5050     return status;
5051 }
5052 
5053 /****************************************************************************/
5054 /*                                                                          */
5055 
5056 JAM_RETURN_TYPE
urj_jam_process_irscan(char * statement_buffer)5057 urj_jam_process_irscan (char *statement_buffer)
5058 /*                                                                          */
5059 /*  Description:    Processes IRSCAN statement, which shifts data through   */
5060 /*                  an instruction register of the JTAG interface           */
5061 /*                                                                          */
5062 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
5063 /*                                                                          */
5064 /****************************************************************************/
5065 {
5066     /* syntax:  IRSCAN <length> [, <data>] [CAPTURE <array>] ; */
5067     /* or:  IRSCAN <length> [, <data>] [COMPARE <array>, <mask>, <result>] ; */
5068 
5069     int index = 0;
5070     int expr_begin = 0;
5071     int expr_end = 0;
5072     int delimiter = 0L;
5073     int32_t count_value = 0L;
5074     int32_t start_index = 0L;
5075     int32_t stop_index = 0L;
5076     char save_ch = 0;
5077     int32_t *tdi_data = NULL;
5078     int32_t *literal_array_data = NULL;
5079     JAME_EXPRESSION_TYPE expr_type = JAM_ILLEGAL_EXPR_TYPE;
5080     JAMS_SYMBOL_RECORD *symbol_record = NULL;
5081     JAMS_HEAP_RECORD *heap_record = NULL;
5082     JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
5083 
5084     if ((urj_jam_version == 2) && (urj_jam_phase != JAM_PROCEDURE_PHASE))
5085     {
5086         return JAMC_PHASE_ERROR;
5087     }
5088 
5089     index = urj_jam_skip_instruction_name (statement_buffer);
5090 
5091     /* locate length */
5092     status = urj_jam_find_argument (&statement_buffer[index],
5093                                 &expr_begin, &expr_end, &delimiter);
5094 
5095     expr_begin += index;
5096     expr_end += index;
5097     delimiter += index;
5098 
5099     if ((status == JAMC_SUCCESS) &&
5100         (statement_buffer[delimiter] != JAMC_COMMA_CHAR))
5101     {
5102         status = JAMC_SYNTAX_ERROR;
5103     }
5104 
5105     if (status == JAMC_SUCCESS)
5106     {
5107         save_ch = statement_buffer[expr_end];
5108         statement_buffer[expr_end] = JAMC_NULL_CHAR;
5109         status =
5110             urj_jam_evaluate_expression (&statement_buffer[expr_begin],
5111                                      &count_value, &expr_type);
5112         statement_buffer[expr_end] = save_ch;
5113     }
5114 
5115     /*
5116      *      Check for integer expression
5117      */
5118     if ((status == JAMC_SUCCESS) &&
5119         (expr_type != JAM_INTEGER_EXPR) &&
5120         (expr_type != JAM_INT_OR_BOOL_EXPR))
5121     {
5122         status = JAMC_TYPE_MISMATCH;
5123     }
5124 
5125     /*
5126      *      Look for array variable with sub-range index
5127      */
5128     if (status == JAMC_SUCCESS)
5129     {
5130         index = delimiter + 1;
5131         status = urj_jam_find_argument (&statement_buffer[index],
5132                                     &expr_begin, &expr_end, &delimiter);
5133 
5134         expr_begin += index;
5135         expr_end += index;
5136         delimiter += index;
5137     }
5138 
5139     if ((status == JAMC_SUCCESS) &&
5140         (statement_buffer[delimiter] != JAMC_COMMA_CHAR) &&
5141         (statement_buffer[delimiter] != JAMC_SEMICOLON_CHAR))
5142     {
5143         status = JAMC_SYNTAX_ERROR;
5144     }
5145 
5146     if (status == JAMC_SUCCESS)
5147     {
5148         save_ch = statement_buffer[expr_end];
5149         statement_buffer[expr_end] = JAMC_NULL_CHAR;
5150         status = urj_jam_get_array_argument (&statement_buffer[expr_begin],
5151                                          &symbol_record, &literal_array_data,
5152                                          &start_index, &stop_index, 0);
5153         statement_buffer[expr_end] = save_ch;
5154     }
5155 
5156     if ((status == JAMC_SUCCESS) &&
5157         (literal_array_data != NULL) &&
5158         (start_index == 0) && (stop_index > count_value - 1))
5159     {
5160         stop_index = count_value - 1;
5161     }
5162 
5163     if (status == JAMC_SUCCESS)
5164     {
5165         if (symbol_record != NULL)
5166         {
5167             heap_record = (JAMS_HEAP_RECORD *) symbol_record->value;
5168 
5169             if (heap_record != NULL)
5170             {
5171                 tdi_data = heap_record->data;
5172             }
5173             else
5174             {
5175                 status = JAMC_INTERNAL_ERROR;
5176             }
5177         }
5178         else if (literal_array_data != NULL)
5179         {
5180             tdi_data = literal_array_data;
5181         }
5182         else
5183         {
5184             status = JAMC_INTERNAL_ERROR;
5185         }
5186     }
5187 
5188     if ((status == JAMC_SUCCESS) &&
5189         (statement_buffer[delimiter] == JAMC_SEMICOLON_CHAR))
5190     {
5191         /*
5192          *      Do a simple IRSCAN operation -- no capture or compare
5193          */
5194         status = urj_jam_do_irscan (count_value, tdi_data, start_index);
5195     }
5196     else if ((status == JAMC_SUCCESS) &&
5197              (statement_buffer[delimiter] == JAMC_COMMA_CHAR))
5198     {
5199         /*
5200          *      Delimiter was a COMMA, so look for CAPTURE or COMPARE keyword
5201          */
5202         index = delimiter + 1;
5203         while (isspace (statement_buffer[index]))
5204         {
5205             ++index;            /* skip over white space */
5206         }
5207 
5208         if ((strncmp (&statement_buffer[index], "CAPTURE", 7) == 0) &&
5209             (isspace (statement_buffer[index + 7])))
5210         {
5211             /*
5212              *      Do an IRSCAN with capture
5213              */
5214             status = urj_jam_process_irscan_capture (&statement_buffer[index + 8],
5215                                                  count_value, tdi_data,
5216                                                  start_index);
5217         }
5218         else if ((strncmp (&statement_buffer[index], "COMPARE", 7) == 0)
5219                  && (isspace (statement_buffer[index + 7])))
5220         {
5221             /*
5222              *      Do an IRSCAN with compare
5223              */
5224             status = urj_jam_process_irscan_compare (&statement_buffer[index + 8],
5225                                                  count_value, tdi_data,
5226                                                  start_index);
5227         }
5228         else
5229         {
5230             status = JAMC_SYNTAX_ERROR;
5231         }
5232     }
5233 
5234     return status;
5235 }
5236 
5237 /****************************************************************************/
5238 /*                                                                          */
5239 
5240 JAM_RETURN_TYPE
urj_jam_process_irstop(char * statement_buffer)5241 urj_jam_process_irstop (char *statement_buffer)
5242 /*                                                                          */
5243 /*  Description:    Sets stop-state for IR scan operations                  */
5244 /*                                                                          */
5245 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
5246 /*                                                                          */
5247 /****************************************************************************/
5248 {
5249     int index = 0;
5250     int expr_begin = 0;
5251     int expr_end = 0;
5252     int delimiter = 0;
5253     JAM_RETURN_TYPE status = JAMC_SUCCESS;
5254     JAME_JTAG_STATE state = JAM_ILLEGAL_JTAG_STATE;
5255 
5256     if ((urj_jam_version == 2) && (urj_jam_phase != JAM_PROCEDURE_PHASE))
5257     {
5258         return JAMC_PHASE_ERROR;
5259     }
5260 
5261     index = urj_jam_skip_instruction_name (statement_buffer);
5262 
5263     /*
5264      *      Get next argument
5265      */
5266     status = urj_jam_find_argument (&statement_buffer[index],
5267                                 &expr_begin, &expr_end, &delimiter);
5268 
5269     expr_begin += index;
5270     expr_end += index;
5271     delimiter += index;
5272 
5273     if ((status == JAMC_SUCCESS) &&
5274         (statement_buffer[delimiter] != JAMC_SEMICOLON_CHAR))
5275     {
5276         status = JAMC_SYNTAX_ERROR;
5277     }
5278 
5279     if (status == JAMC_SUCCESS)
5280     {
5281         statement_buffer[expr_end] = JAMC_NULL_CHAR;
5282         state = urj_jam_get_jtag_state_from_name (&statement_buffer[expr_begin]);
5283 
5284         if (state == JAM_ILLEGAL_JTAG_STATE)
5285         {
5286             status = JAMC_SYNTAX_ERROR;
5287         }
5288         else
5289         {
5290             /*
5291              *      Set IRSCAN stop state to the specified state
5292              */
5293             status = urj_jam_set_irstop_state (state);
5294         }
5295     }
5296 
5297     return status;
5298 }
5299 
5300 /****************************************************************************/
5301 /*                                                                          */
5302 
urj_jam_copy_array_subrange(int32_t * source_heap_data,int32_t source_subrange_begin,int32_t source_subrange_end,int32_t * dest_heap_data,int32_t dest_subrange_begin,int32_t dest_subrange_end)5303 JAM_RETURN_TYPE urj_jam_copy_array_subrange
5304     (int32_t *source_heap_data,
5305      int32_t source_subrange_begin,
5306      int32_t source_subrange_end,
5307      int32_t *dest_heap_data,
5308      int32_t dest_subrange_begin, int32_t dest_subrange_end)
5309 /*                                                                          */
5310 /*  Description:    Copies bits from one BOOLEAN array buffer to another    */
5311 /*                                                                          */
5312 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
5313 /*                                                                          */
5314 /****************************************************************************/
5315 {
5316     int32_t source_length = 1 + source_subrange_end - source_subrange_begin;
5317     int32_t dest_length = 1 + dest_subrange_end - dest_subrange_begin;
5318     int32_t length = source_length;
5319     int32_t index = 0L;
5320     int32_t source_index = 0L;
5321     int32_t dest_index = 0L;
5322     JAM_RETURN_TYPE status = JAMC_SUCCESS;
5323 
5324     /* find minimum of source_length and dest_length */
5325     if (length > dest_length)
5326         length = dest_length;
5327 
5328     if (length <= 0L)
5329     {
5330         status = JAMC_BOUNDS_ERROR;
5331     }
5332     else
5333     {
5334         /* copy the bits */
5335         for (index = 0L; index < length; ++index)
5336         {
5337             source_index = index + source_subrange_begin;
5338             dest_index = index + dest_subrange_begin;
5339 
5340             if (source_heap_data[source_index >> 5] &
5341                 (1L << (source_index & 0x1f)))
5342             {
5343                 /* set a single bit */
5344                 dest_heap_data[dest_index >> 5] |=
5345                     (1L << (dest_index & 0x1f));
5346             }
5347             else
5348             {
5349                 /* clear a single bit */
5350                 dest_heap_data[dest_index >> 5] &=
5351                     (~(uint32_t) (1L << (dest_index & 0x1f)));
5352             }
5353         }
5354     }
5355 
5356     return status;
5357 }
5358 
5359 BOOL
urj_jam_check_assignment(char * statement_buffer)5360 urj_jam_check_assignment (char *statement_buffer)
5361 {
5362     BOOL assignment = false;
5363     int index = 0;
5364     char save_ch = 0;
5365     int variable_begin = 0;
5366     int variable_end = 0;
5367     JAMS_SYMBOL_RECORD *symbol_record = NULL;
5368 
5369     while ((jam_is_name_char (statement_buffer[index])) &&
5370            (index < JAMC_MAX_STATEMENT_LENGTH))
5371     {
5372         ++index;                /* skip over variable name */
5373     }
5374 
5375     if (index < JAMC_MAX_NAME_LENGTH)
5376     {
5377         /* check if this is a variable name */
5378         variable_end = index;
5379         save_ch = statement_buffer[variable_end];
5380         statement_buffer[variable_end] = JAMC_NULL_CHAR;
5381 
5382         if (urj_jam_get_symbol_record (&statement_buffer[variable_begin],
5383                                    &symbol_record) == JAMC_SUCCESS)
5384         {
5385             if ((symbol_record->type == JAM_INTEGER_SYMBOL) ||
5386                 (symbol_record->type == JAM_BOOLEAN_SYMBOL) ||
5387                 (symbol_record->type == JAM_INTEGER_ARRAY_WRITABLE) ||
5388                 (symbol_record->type == JAM_BOOLEAN_ARRAY_WRITABLE) ||
5389                 (symbol_record->type == JAM_INTEGER_ARRAY_INITIALIZED) ||
5390                 (symbol_record->type == JAM_BOOLEAN_ARRAY_INITIALIZED))
5391             {
5392                 assignment = true;
5393             }
5394         }
5395 
5396         statement_buffer[variable_end] = save_ch;
5397     }
5398 
5399     return assignment;
5400 }
5401 
5402 /****************************************************************************/
5403 /*                                                                          */
5404 
5405 JAM_RETURN_TYPE
urj_jam_process_assignment(char * statement_buffer,BOOL let)5406 urj_jam_process_assignment (char *statement_buffer, BOOL let)
5407 /*                                                                          */
5408 /*  Description:    Processes a LET (assignment) statement.                 */
5409 /*                                                                          */
5410 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
5411 /*                                                                          */
5412 /****************************************************************************/
5413 {
5414     int index = 0;
5415     int variable_begin = 0;
5416     int variable_end = 0;
5417     int dim_begin = 0;
5418     int dim_end = 0;
5419     int expr_begin = 0;
5420     int expr_end = 0;
5421     int bracket_count = 0;
5422     int32_t dim_value = 0L;
5423     int32_t assign_value = 0L;
5424     char save_ch = 0;
5425     int32_t source_subrange_begin = 0L;
5426     int32_t source_subrange_end = 0L;
5427     int32_t dest_subrange_begin = 0L;
5428     int32_t dest_subrange_end = 0L;
5429     BOOL is_array = false;
5430     BOOL full_array = false;
5431     BOOL array_subrange = false;
5432     int32_t *source_heap_data = NULL;
5433     int32_t *dest_heap_data = NULL;
5434     int32_t *literal_array_data = NULL;
5435     JAME_EXPRESSION_TYPE assign_type = JAM_ILLEGAL_EXPR_TYPE;
5436     JAME_EXPRESSION_TYPE expr_type = JAM_ILLEGAL_EXPR_TYPE;
5437     JAMS_SYMBOL_RECORD *symbol_record = NULL;
5438     JAMS_HEAP_RECORD *heap_record = NULL;
5439     JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
5440 
5441 
5442     if (let & (urj_jam_version == 0))
5443         urj_jam_version = 1;
5444 
5445     if ((!let) & (urj_jam_version == 0))
5446         urj_jam_version = 2;
5447 
5448     if (((!let) & (urj_jam_version == 1)) || (let & (urj_jam_version == 2)))
5449     {
5450         return JAMC_SYNTAX_ERROR;
5451     }
5452 
5453     if ((urj_jam_version == 2) && (urj_jam_phase != JAM_PROCEDURE_PHASE))
5454     {
5455         return JAMC_PHASE_ERROR;
5456     }
5457 
5458     if (let)
5459     {
5460         index = urj_jam_skip_instruction_name (statement_buffer);
5461     }
5462 
5463     if (isalpha (statement_buffer[index]))
5464     {
5465         /* locate variable name */
5466         variable_begin = index;
5467         while ((jam_is_name_char (statement_buffer[index])) &&
5468                (index < JAMC_MAX_STATEMENT_LENGTH))
5469         {
5470             ++index;            /* skip over variable name */
5471         }
5472         variable_end = index;
5473 
5474         while ((isspace (statement_buffer[index])) &&
5475                (index < JAMC_MAX_STATEMENT_LENGTH))
5476         {
5477             ++index;            /* skip over white space */
5478         }
5479 
5480         status = JAMC_SUCCESS;
5481 
5482         if (statement_buffer[index] == JAMC_LBRACKET_CHAR)
5483         {
5484             /*
5485              *      Assignment to array element
5486              */
5487             ++index;
5488             is_array = true;
5489             dim_begin = index;
5490             while ((isspace (statement_buffer[dim_begin])) &&
5491                    (dim_begin < JAMC_MAX_STATEMENT_LENGTH))
5492             {
5493                 ++dim_begin;    /* skip over white space */
5494             }
5495             while (((statement_buffer[index] != JAMC_RBRACKET_CHAR) ||
5496                     (bracket_count > 0)) &&
5497                    (index < JAMC_MAX_STATEMENT_LENGTH))
5498             {
5499                 if (statement_buffer[index] == JAMC_LBRACKET_CHAR)
5500                 {
5501                     ++bracket_count;
5502                 }
5503                 else if (statement_buffer[index] == JAMC_RBRACKET_CHAR)
5504                 {
5505                     --bracket_count;
5506                 }
5507 
5508                 ++index;        /* find matching bracket */
5509             }
5510             if (statement_buffer[index] == JAMC_RBRACKET_CHAR)
5511             {
5512                 dim_end = index;
5513             }
5514 
5515             if (dim_end == dim_begin)
5516             {
5517                 /* full array notation */
5518                 full_array = true;
5519             }
5520             else if (dim_end > dim_begin)
5521             {
5522                 /* look for ".." in array index expression */
5523                 index = dim_begin;
5524                 while ((index < dim_end) && !array_subrange)
5525                 {
5526                     if ((statement_buffer[index] == JAMC_PERIOD_CHAR) &&
5527                         (statement_buffer[index + 1] == JAMC_PERIOD_CHAR))
5528                     {
5529                         array_subrange = true;
5530                     }
5531                     ++index;
5532                 }
5533             }
5534             else
5535             {
5536                 /* right bracket not found */
5537                 status = JAMC_SYNTAX_ERROR;
5538             }
5539 
5540             if (status == JAMC_SUCCESS)
5541             {
5542                 index = dim_end + 1;
5543                 while ((isspace (statement_buffer[index])) &&
5544                        (index < JAMC_MAX_STATEMENT_LENGTH))
5545                 {
5546                     ++index;    /* skip over white space */
5547                 }
5548 
5549                 /* get pointer to symbol record */
5550                 save_ch = statement_buffer[variable_end];
5551                 statement_buffer[variable_end] = JAMC_NULL_CHAR;
5552                 status =
5553                     urj_jam_get_symbol_record (&statement_buffer[variable_begin],
5554                                            &symbol_record);
5555                 statement_buffer[variable_end] = save_ch;
5556 
5557                 /* check array type */
5558                 if (status == JAMC_SUCCESS)
5559                 {
5560                     switch (symbol_record->type)
5561                     {
5562                     case JAM_INTEGER_ARRAY_WRITABLE:
5563                         assign_type = JAM_INTEGER_EXPR;
5564                         break;
5565 
5566                     case JAM_BOOLEAN_ARRAY_WRITABLE:
5567                         assign_type = JAM_BOOLEAN_EXPR;
5568                         break;
5569 
5570                     case JAM_INTEGER_ARRAY_INITIALIZED:
5571                     case JAM_BOOLEAN_ARRAY_INITIALIZED:
5572                         status = JAMC_ASSIGN_TO_CONST;
5573                         break;
5574 
5575                     default:
5576                         status = JAMC_TYPE_MISMATCH;
5577                         break;
5578                     }
5579                 }
5580 
5581                 /* get pointer to heap record */
5582                 if (status == JAMC_SUCCESS)
5583                 {
5584                     heap_record = (JAMS_HEAP_RECORD *) symbol_record->value;
5585 
5586                     if (heap_record == NULL)
5587                     {
5588                         status = JAMC_INTERNAL_ERROR;
5589                     }
5590                     else
5591                     {
5592                         dest_heap_data = heap_record->data;
5593                     }
5594                 }
5595             }
5596 
5597             if (status == JAMC_SUCCESS)
5598             {
5599                 if (full_array || array_subrange)
5600                 {
5601                     if (assign_type == JAM_BOOLEAN_EXPR)
5602                     {
5603                         if (full_array)
5604                         {
5605                             dest_subrange_begin = 0L;
5606                             dest_subrange_end = heap_record->dimension - 1L;
5607                             array_subrange = true;
5608                         }
5609                         else
5610                         {
5611                             save_ch = statement_buffer[dim_end];
5612                             statement_buffer[dim_end] = JAMC_NULL_CHAR;
5613                             status = urj_jam_get_array_subrange (symbol_record,
5614                                                              &statement_buffer
5615                                                              [dim_begin],
5616                                                              &dest_subrange_begin,
5617                                                              &dest_subrange_end);
5618                             statement_buffer[dim_end] = save_ch;
5619 
5620                             /* check array bounds */
5621                             if ((status == JAMC_SUCCESS) &&
5622                                 ((dest_subrange_begin < 0L) ||
5623                                  (dest_subrange_begin >=
5624                                   heap_record->dimension)
5625                                  || (dest_subrange_end < 0L)
5626                                  || (dest_subrange_end >=
5627                                      heap_record->dimension)))
5628                             {
5629                                 status = JAMC_BOUNDS_ERROR;
5630                             }
5631                         }
5632                     }
5633                     else
5634                     {
5635                         /* can't assign to an integer array */
5636                         status = JAMC_SYNTAX_ERROR;
5637                     }
5638                 }
5639                 else
5640                 {
5641                     /* assign to array element */
5642                     save_ch = statement_buffer[dim_end];
5643                     statement_buffer[dim_end] = JAMC_NULL_CHAR;
5644                     status =
5645                         urj_jam_evaluate_expression (&statement_buffer[dim_begin],
5646                                                  &dim_value, &expr_type);
5647                     statement_buffer[dim_end] = save_ch;
5648 
5649                     /*
5650                      *      Check for integer expression
5651                      */
5652                     if ((status == JAMC_SUCCESS) &&
5653                         (expr_type != JAM_INTEGER_EXPR) &&
5654                         (expr_type != JAM_INT_OR_BOOL_EXPR))
5655                     {
5656                         status = JAMC_TYPE_MISMATCH;
5657                     }
5658                 }
5659             }
5660         }
5661         else
5662         {
5663             /*
5664              *      Get type of variable on left-hand-side
5665              */
5666             save_ch = statement_buffer[variable_end];
5667             statement_buffer[variable_end] = JAMC_NULL_CHAR;
5668             status =
5669                 urj_jam_get_symbol_record (&statement_buffer[variable_begin],
5670                                        &symbol_record);
5671             statement_buffer[variable_end] = save_ch;
5672 
5673             if (status == JAMC_SUCCESS)
5674             {
5675                 switch (symbol_record->type)
5676                 {
5677                 case JAM_INTEGER_SYMBOL:
5678                     assign_type = JAM_INTEGER_EXPR;
5679                     break;
5680 
5681                 case JAM_BOOLEAN_SYMBOL:
5682                     assign_type = JAM_BOOLEAN_EXPR;
5683                     break;
5684 
5685                 default:
5686                     status = JAMC_TYPE_MISMATCH;
5687                     break;
5688                 }
5689             }
5690         }
5691 
5692         /*
5693          *      Evaluate assignment expression
5694          */
5695         if (status == JAMC_SUCCESS)
5696         {
5697             status = JAMC_SYNTAX_ERROR;
5698 
5699             if (statement_buffer[index] == JAMC_EQUAL_CHAR)
5700             {
5701                 /*
5702                  *      Evaluate assignment expression
5703                  */
5704                 expr_begin = index + 1;
5705                 while ((isspace (statement_buffer[expr_begin])) &&
5706                        (expr_begin < JAMC_MAX_STATEMENT_LENGTH))
5707                 {
5708                     ++expr_begin;       /* skip over white space */
5709                 }
5710                 while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
5711                        (index < JAMC_MAX_STATEMENT_LENGTH))
5712                 {
5713                     ++index;
5714                 }
5715                 while ((statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
5716                        (index > 0))
5717                 {
5718                     --index;
5719                 }
5720                 expr_end = index;
5721 
5722                 if (expr_end > expr_begin)
5723                 {
5724                     if (array_subrange)
5725                     {
5726                         symbol_record = NULL;
5727                         save_ch = statement_buffer[expr_end];
5728                         statement_buffer[expr_end] = JAMC_NULL_CHAR;
5729                         status =
5730                             urj_jam_get_array_argument (&statement_buffer
5731                                                     [expr_begin],
5732                                                     &symbol_record,
5733                                                     &literal_array_data,
5734                                                     &source_subrange_begin,
5735                                                     &source_subrange_end, 0);
5736                         statement_buffer[expr_end] = save_ch;
5737 
5738                         if (status == JAMC_SUCCESS)
5739                         {
5740                             if (symbol_record != NULL)
5741                             {
5742                                 if ((symbol_record->type ==
5743                                      JAM_BOOLEAN_ARRAY_WRITABLE) ||
5744                                     (symbol_record->type ==
5745                                      JAM_BOOLEAN_ARRAY_INITIALIZED))
5746                                 {
5747                                     heap_record = (JAMS_HEAP_RECORD *)
5748                                         symbol_record->value;
5749 
5750                                     /* check array bounds */
5751                                     if ((source_subrange_begin < 0L) ||
5752                                         (source_subrange_begin >=
5753                                          heap_record->dimension) ||
5754                                         (source_subrange_end < 0L) ||
5755                                         (source_subrange_end >=
5756                                          heap_record->dimension))
5757                                     {
5758                                         status = JAMC_BOUNDS_ERROR;
5759                                     }
5760                                     else
5761                                     {
5762                                         source_heap_data = heap_record->data;
5763                                     }
5764                                 }
5765                                 else
5766                                 {
5767                                     status = JAMC_TYPE_MISMATCH;
5768                                 }
5769                             }
5770                             else if (literal_array_data != NULL)
5771                             {
5772                                 source_heap_data = literal_array_data;
5773                             }
5774                             else
5775                             {
5776                                 status = JAMC_INTERNAL_ERROR;
5777                             }
5778                         }
5779                     }
5780                     else
5781                     {
5782                         save_ch = statement_buffer[expr_end];
5783                         statement_buffer[expr_end] = JAMC_NULL_CHAR;
5784                         status =
5785                             urj_jam_evaluate_expression (&statement_buffer
5786                                                      [expr_begin],
5787                                                      &assign_value,
5788                                                      &expr_type);
5789                         statement_buffer[expr_end] = save_ch;
5790                     }
5791                 }
5792             }
5793         }
5794 
5795         if (status == JAMC_SUCCESS)
5796         {
5797             /*
5798              *      Check type of expression against type of variable
5799              *      being assigned
5800              */
5801             if (array_subrange)
5802             {
5803                 /* copy array data */
5804                 status = urj_jam_copy_array_subrange (source_heap_data,
5805                                                   source_subrange_begin,
5806                                                   source_subrange_end,
5807                                                   dest_heap_data,
5808                                                   dest_subrange_begin,
5809                                                   dest_subrange_end);
5810             }
5811             else if ((expr_type != JAM_ILLEGAL_EXPR_TYPE) &&
5812                      (assign_type != JAM_ILLEGAL_EXPR_TYPE) &&
5813                      ((expr_type == assign_type) ||
5814                       (expr_type == JAM_INT_OR_BOOL_EXPR)))
5815             {
5816                 /*
5817                  *      Set the variable to the computed value
5818                  */
5819                 if (is_array)
5820                 {
5821                     /* check array bounds */
5822                     if ((dim_value >= 0) &&
5823                         (dim_value < heap_record->dimension))
5824                     {
5825                         if (assign_type == JAM_INTEGER_EXPR)
5826                         {
5827                             dest_heap_data[dim_value] = assign_value;
5828                         }
5829                         else if (assign_type == JAM_BOOLEAN_EXPR)
5830                         {
5831                             if (assign_value == 0)
5832                             {
5833                                 /* clear a single bit */
5834                                 dest_heap_data[dim_value >> 5] &=
5835                                     (~(uint32_t) (1L << (dim_value & 0x1f)));
5836                             }
5837                             else
5838                             {
5839                                 /* set a single bit */
5840                                 dest_heap_data[dim_value >> 5] |=
5841                                     (1L << (dim_value & 0x1f));
5842                             }
5843                         }
5844                         else
5845                         {
5846                             status = JAMC_INTERNAL_ERROR;
5847                         }
5848                     }
5849                     else
5850                     {
5851                         status = JAMC_BOUNDS_ERROR;
5852                     }
5853                 }
5854                 else
5855                 {
5856                     symbol_record->value = assign_value;
5857                 }
5858             }
5859             else
5860             {
5861                 status = JAMC_TYPE_MISMATCH;
5862             }
5863         }
5864     }
5865 
5866     return status;
5867 }
5868 
5869 /****************************************************************************/
5870 /*                                                                          */
5871 
5872 JAM_RETURN_TYPE
urj_jam_process_next(char * statement_buffer)5873 urj_jam_process_next (char *statement_buffer)
5874 /*                                                                          */
5875 /*  Description:    Processes a NEXT statement.  The NEXT statement is      */
5876 /*                  used to mark the bottom of a FOR loop.  When a NEXT     */
5877 /*                  statement is processed, there must be a corresponding   */
5878 /*                  FOR loop stack record on top of the stack.              */
5879 /*                                                                          */
5880 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
5881 /*                                                                          */
5882 /****************************************************************************/
5883 {
5884     int index = 0;
5885     int variable_begin = 0;
5886     int variable_end = 0;
5887     char save_ch = 0;
5888     JAMS_SYMBOL_RECORD *symbol_record = NULL;
5889     JAMS_STACK_RECORD *stack_record = NULL;
5890     JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
5891 
5892     if ((urj_jam_version == 2) && (urj_jam_phase != JAM_PROCEDURE_PHASE))
5893     {
5894         return JAMC_PHASE_ERROR;
5895     }
5896 
5897     index = urj_jam_skip_instruction_name (statement_buffer);
5898 
5899     if (isalpha (statement_buffer[index]))
5900     {
5901         /* locate variable name */
5902         variable_begin = index;
5903         while ((jam_is_name_char (statement_buffer[index])) &&
5904                (index < JAMC_MAX_STATEMENT_LENGTH))
5905         {
5906             ++index;            /* skip over variable name */
5907         }
5908         variable_end = index;
5909 
5910         while ((isspace (statement_buffer[index])) &&
5911                (index < JAMC_MAX_STATEMENT_LENGTH))
5912         {
5913             ++index;            /* skip over white space */
5914         }
5915 
5916         if (statement_buffer[index] == JAMC_SEMICOLON_CHAR)
5917         {
5918             /*
5919              *      Look in symbol table for iterator variable
5920              */
5921             save_ch = statement_buffer[variable_end];
5922             statement_buffer[variable_end] = JAMC_NULL_CHAR;
5923             status =
5924                 urj_jam_get_symbol_record (&statement_buffer[variable_begin],
5925                                        &symbol_record);
5926             statement_buffer[variable_end] = save_ch;
5927 
5928             if ((status == JAMC_SUCCESS) &&
5929                 (symbol_record->type != JAM_INTEGER_SYMBOL))
5930             {
5931                 status = JAMC_TYPE_MISMATCH;
5932             }
5933         }
5934 
5935         if (status == JAMC_SUCCESS)
5936         {
5937             /*
5938              *      Get stack record at top of stack
5939              */
5940             stack_record = urj_jam_peek_stack_record ();
5941 
5942             /*
5943              *      Compare iterator to stack record
5944              */
5945             if ((stack_record == NULL) ||
5946                 (stack_record->type != JAM_STACK_FOR_NEXT) ||
5947                 (stack_record->iterator != symbol_record))
5948             {
5949                 status = JAMC_NEXT_UNEXPECTED;
5950             }
5951             else
5952             {
5953                 /*
5954                  *      Check if loop has run to completion
5955                  */
5956                 if (((stack_record->step_value > 0) &&
5957                      (symbol_record->value >= stack_record->stop_value)) ||
5958                     ((stack_record->step_value < 0) &&
5959                      (symbol_record->value <= stack_record->stop_value)))
5960                 {
5961                     /*
5962                      *      Loop has run to completion -- pop the stack record.
5963                      *      (Do not jump back to FOR statement position.)
5964                      */
5965                     status = urj_jam_pop_stack_record ();
5966                 }
5967                 else
5968                 {
5969                     /*
5970                      *      Increment (or step) the iterator variable
5971                      */
5972                     symbol_record->value += stack_record->step_value;
5973 
5974                     /*
5975                      *      Jump back to the top of the loop
5976                      */
5977                     if (urj_jam_seek (stack_record->for_position) == 0)
5978                     {
5979                         urj_jam_current_file_position =
5980                             stack_record->for_position;
5981                         status = JAMC_SUCCESS;
5982                     }
5983                     else
5984                     {
5985                         status = JAMC_IO_ERROR;
5986                     }
5987                 }
5988             }
5989         }
5990     }
5991 
5992     return status;
5993 }
5994 
5995 /****************************************************************************/
5996 /*                                                                          */
5997 
5998 JAM_RETURN_TYPE
urj_jam_process_padding(char * statement_buffer)5999 urj_jam_process_padding (char *statement_buffer)
6000 /*                                                                          */
6001 /*  Description:    Processes a PADDING statement.  This sets the number    */
6002 /*                  of padding bits to be used before and after the data    */
6003 /*                  indicated for each DRSCAN and IRSCAN operation.         */
6004 /*                                                                          */
6005 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
6006 /*                                                                          */
6007 /****************************************************************************/
6008 {
6009     int index = 0;
6010     int argc = 0;
6011     int expr_begin = 0;
6012     int expr_end = 0;
6013     int delimiter = 0;
6014     char save_ch = 0;
6015     int32_t padding[4] = { 0 };
6016     JAME_EXPRESSION_TYPE expr_type = JAM_ILLEGAL_EXPR_TYPE;
6017     JAM_RETURN_TYPE status = JAMC_SUCCESS;
6018 
6019     if (urj_jam_version == 0)
6020         urj_jam_version = 1;
6021 
6022     if (urj_jam_version == 2)
6023     {
6024         /* The PADDING statement is not supported in Jam 2.0 */
6025         status = JAMC_SYNTAX_ERROR;
6026     }
6027 
6028     index = urj_jam_skip_instruction_name (statement_buffer);
6029 
6030     for (argc = 0; (argc < 4) && (status == JAMC_SUCCESS); ++argc)
6031     {
6032         status = urj_jam_find_argument (&statement_buffer[index],
6033                                     &expr_begin, &expr_end, &delimiter);
6034 
6035         if (status == JAMC_SUCCESS)
6036         {
6037             padding[argc] = -1L;
6038 
6039             expr_begin += index;
6040             expr_end += index;
6041             delimiter += index;
6042 
6043             if (((argc < 3) &&
6044                  (statement_buffer[delimiter] == JAMC_COMMA_CHAR)) ||
6045                 ((argc == 3) &&
6046                  (statement_buffer[delimiter] == JAMC_SEMICOLON_CHAR)))
6047             {
6048                 save_ch = statement_buffer[expr_end];
6049                 statement_buffer[expr_end] = JAMC_NULL_CHAR;
6050                 status =
6051                     urj_jam_evaluate_expression (&statement_buffer[expr_begin],
6052                                              &padding[argc], &expr_type);
6053                 statement_buffer[expr_end] = save_ch;
6054 
6055                 /*
6056                  *      Check for integer expression
6057                  */
6058                 if ((status == JAMC_SUCCESS) &&
6059                     (expr_type != JAM_INTEGER_EXPR) &&
6060                     (expr_type != JAM_INT_OR_BOOL_EXPR))
6061                 {
6062                     status = JAMC_TYPE_MISMATCH;
6063                 }
6064 
6065                 /*
6066                  *      Check the range -- padding value must be between 0 and 1000
6067                  */
6068                 if ((status == JAMC_SUCCESS) &&
6069                     ((padding[argc] < 0L) || (padding[argc] > 1000L)))
6070                 {
6071                     status = JAMC_SYNTAX_ERROR;
6072                 }
6073                 else
6074                 {
6075                     index = expr_end + 1;
6076                 }
6077             }
6078             else
6079             {
6080                 status = JAMC_SYNTAX_ERROR;
6081             }
6082         }
6083     }
6084 
6085     /*
6086      *      Store the new padding values
6087      */
6088     if (status == JAMC_SUCCESS)
6089     {
6090         status = urj_jam_set_dr_preamble ((int) padding[0], 0, NULL);
6091 
6092         if (status == JAMC_SUCCESS)
6093         {
6094             status = urj_jam_set_dr_postamble ((int) padding[1], 0, NULL);
6095         }
6096 
6097         if (status == JAMC_SUCCESS)
6098         {
6099             status = urj_jam_set_ir_preamble ((int) padding[2], 0, NULL);
6100         }
6101 
6102         if (status == JAMC_SUCCESS)
6103         {
6104             status = urj_jam_set_ir_postamble ((int) padding[3], 0, NULL);
6105         }
6106     }
6107 
6108     return status;
6109 }
6110 
6111 /****************************************************************************/
6112 /*                                                                          */
6113 
6114 JAM_RETURN_TYPE
urj_jam_process_pop(char * statement_buffer)6115 urj_jam_process_pop (char *statement_buffer)
6116 /*                                                                          */
6117 /*  Description:    Pops a data element (integer or Boolean) from the       */
6118 /*                  internal stack.  The data value is stored in the        */
6119 /*                  variable specified.  If the type of data is not         */
6120 /*                  compatible with the variable type, a type mismatch      */
6121 /*                  error results.                                          */
6122 /*                                                                          */
6123 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
6124 /*                                                                          */
6125 /****************************************************************************/
6126 {
6127     int index = 0;
6128     int32_t push_value = 0L;
6129     int32_t dim_value = 0L;
6130     int variable_begin = 0;
6131     int variable_end = 0;
6132     int dim_begin = 0;
6133     int dim_end = 0;
6134     int bracket_count = 0;
6135     char save_ch = 0;
6136     BOOL is_array = false;
6137     int32_t *heap_data = NULL;
6138     JAMS_SYMBOL_RECORD *symbol_record = NULL;
6139     JAMS_STACK_RECORD *stack_record = NULL;
6140     JAMS_HEAP_RECORD *heap_record = NULL;
6141     JAME_EXPRESSION_TYPE assign_type = JAM_ILLEGAL_EXPR_TYPE;
6142     JAME_EXPRESSION_TYPE value_type = JAM_ILLEGAL_EXPR_TYPE;
6143     JAME_EXPRESSION_TYPE expr_type = JAM_ILLEGAL_EXPR_TYPE;
6144     JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
6145 
6146     if ((urj_jam_version == 2) && (urj_jam_phase != JAM_PROCEDURE_PHASE))
6147     {
6148         return JAMC_PHASE_ERROR;
6149     }
6150 
6151     index = urj_jam_skip_instruction_name (statement_buffer);
6152 
6153     /*
6154      *      Get the variable name
6155      */
6156     if (isalpha (statement_buffer[index]))
6157     {
6158         variable_begin = index;
6159         while ((jam_is_name_char (statement_buffer[index])) &&
6160                (index < JAMC_MAX_STATEMENT_LENGTH))
6161         {
6162             ++index;            /* skip over variable name */
6163         }
6164         variable_end = index;
6165 
6166         while ((isspace (statement_buffer[index])) &&
6167                (index < JAMC_MAX_STATEMENT_LENGTH))
6168         {
6169             ++index;            /* skip over white space */
6170         }
6171 
6172         if (statement_buffer[index] == JAMC_LBRACKET_CHAR)
6173         {
6174             /*
6175              *      Pop value into array element
6176              */
6177             ++index;
6178             is_array = true;
6179             dim_begin = index;
6180             while (((statement_buffer[index] != JAMC_RBRACKET_CHAR) ||
6181                     (bracket_count > 0)) &&
6182                    (index < JAMC_MAX_STATEMENT_LENGTH))
6183             {
6184                 if (statement_buffer[index] == JAMC_LBRACKET_CHAR)
6185                 {
6186                     ++bracket_count;
6187                 }
6188                 else if (statement_buffer[index] == JAMC_RBRACKET_CHAR)
6189                 {
6190                     --bracket_count;
6191                 }
6192 
6193                 ++index;        /* find matching bracket */
6194             }
6195             if (statement_buffer[index] == JAMC_RBRACKET_CHAR)
6196             {
6197                 dim_end = index;
6198                 ++index;
6199             }
6200             while ((isspace (statement_buffer[index])) &&
6201                    (index < JAMC_MAX_STATEMENT_LENGTH))
6202             {
6203                 ++index;        /* skip over white space */
6204             }
6205 
6206             if (dim_end > dim_begin)
6207             {
6208                 save_ch = statement_buffer[dim_end];
6209                 statement_buffer[dim_end] = JAMC_NULL_CHAR;
6210                 status =
6211                     urj_jam_evaluate_expression (&statement_buffer[dim_begin],
6212                                              &dim_value, &expr_type);
6213                 statement_buffer[dim_end] = save_ch;
6214             }
6215 
6216             /*
6217              *      Check for integer expression
6218              */
6219             if ((status == JAMC_SUCCESS) &&
6220                 (expr_type != JAM_INTEGER_EXPR) &&
6221                 (expr_type != JAM_INT_OR_BOOL_EXPR))
6222             {
6223                 status = JAMC_TYPE_MISMATCH;
6224             }
6225 
6226             if (status == JAMC_SUCCESS)
6227             {
6228                 /* get pointer to symbol record */
6229                 save_ch = statement_buffer[variable_end];
6230                 statement_buffer[variable_end] = JAMC_NULL_CHAR;
6231                 status =
6232                     urj_jam_get_symbol_record (&statement_buffer[variable_begin],
6233                                            &symbol_record);
6234                 statement_buffer[variable_end] = save_ch;
6235 
6236                 /* check array type */
6237                 if (status == JAMC_SUCCESS)
6238                 {
6239                     switch (symbol_record->type)
6240                     {
6241                     case JAM_INTEGER_ARRAY_WRITABLE:
6242                         assign_type = JAM_INTEGER_EXPR;
6243                         break;
6244 
6245                     case JAM_BOOLEAN_ARRAY_WRITABLE:
6246                         assign_type = JAM_BOOLEAN_EXPR;
6247                         break;
6248 
6249                     case JAM_INTEGER_ARRAY_INITIALIZED:
6250                     case JAM_BOOLEAN_ARRAY_INITIALIZED:
6251                         status = JAMC_ASSIGN_TO_CONST;
6252                         break;
6253 
6254                     default:
6255                         status = JAMC_TYPE_MISMATCH;
6256                         break;
6257                     }
6258                 }
6259 
6260                 /* get pointer to heap record */
6261                 if (status == JAMC_SUCCESS)
6262                 {
6263                     heap_record = (JAMS_HEAP_RECORD *) symbol_record->value;
6264 
6265                     if (heap_record == NULL)
6266                     {
6267                         status = JAMC_INTERNAL_ERROR;
6268                     }
6269                     else
6270                     {
6271                         heap_data = &heap_record->data[0];
6272                     }
6273                 }
6274             }
6275         }
6276         else
6277         {
6278             /*
6279              *      Poping value into scalar (not array) variable
6280              */
6281             if (statement_buffer[index] == JAMC_SEMICOLON_CHAR)
6282             {
6283                 /*
6284                  *      Get variable type
6285                  */
6286                 save_ch = statement_buffer[variable_end];
6287                 statement_buffer[variable_end] = JAMC_NULL_CHAR;
6288                 status =
6289                     urj_jam_get_symbol_record (&statement_buffer[variable_begin],
6290                                            &symbol_record);
6291                 statement_buffer[variable_end] = save_ch;
6292 
6293                 if (status == JAMC_SUCCESS)
6294                 {
6295                     switch (symbol_record->type)
6296                     {
6297                     case JAM_INTEGER_SYMBOL:
6298                         assign_type = JAM_INTEGER_EXPR;
6299                         break;
6300 
6301                     case JAM_BOOLEAN_SYMBOL:
6302                         assign_type = JAM_BOOLEAN_EXPR;
6303                         break;
6304 
6305                     default:
6306                         status = JAMC_TYPE_MISMATCH;
6307                         break;
6308                     }
6309                 }
6310             }
6311             else
6312             {
6313                 status = JAMC_SYNTAX_ERROR;
6314             }
6315         }
6316 
6317         /*
6318          *      Get stack record at top of stack
6319          */
6320         stack_record = urj_jam_peek_stack_record ();
6321 
6322         /*
6323          *      Check that stack record corresponds to a PUSH statement
6324          */
6325         if ((stack_record != NULL) &&
6326             (stack_record->type == JAM_STACK_PUSH_POP))
6327         {
6328             /*
6329              *      Stack record is the correct type -- pop it off the stack.
6330              */
6331             push_value = stack_record->push_value;
6332             status = urj_jam_pop_stack_record ();
6333 
6334             /*
6335              *      Now set the variable to the push value
6336              */
6337             if (status == JAMC_SUCCESS)
6338             {
6339                 /*
6340                  *      Check type of expression against type of variable
6341                  *      being assigned
6342                  */
6343                 if ((push_value == 0) || (push_value == 1))
6344                 {
6345                     value_type = JAM_INT_OR_BOOL_EXPR;
6346                 }
6347                 else
6348                     value_type = JAM_INTEGER_EXPR;
6349 
6350                 if ((assign_type != JAM_ILLEGAL_EXPR_TYPE) &&
6351                     ((value_type == assign_type) ||
6352                      (value_type == JAM_INT_OR_BOOL_EXPR)))
6353                 {
6354                     /*
6355                      *      Set the variable to the computed value
6356                      */
6357                     if (is_array)
6358                     {
6359                         if (assign_type == JAM_INTEGER_EXPR)
6360                         {
6361                             heap_data[dim_value] = push_value;
6362                         }
6363                         else if (assign_type == JAM_BOOLEAN_EXPR)
6364                         {
6365                             if (push_value == 0)
6366                             {
6367                                 /* clear a single bit */
6368                                 heap_data[dim_value >> 5] &=
6369                                     (~(uint32_t) (1L << (dim_value & 0x1f)));
6370                             }
6371                             else
6372                             {
6373                                 /* set a single bit */
6374                                 heap_data[dim_value >> 5] |=
6375                                     (1L << (dim_value & 0x1f));
6376                             }
6377                         }
6378                         else
6379                             status = JAMC_INTERNAL_ERROR;
6380                     }
6381                     else
6382                     {
6383                         symbol_record->value = push_value;
6384                     }
6385                 }
6386                 else
6387                 {
6388                     status = JAMC_TYPE_MISMATCH;
6389                 }
6390             }
6391         }
6392         else
6393         {
6394             /*
6395              *      Top of stack did not have a PUSH/POP record
6396              */
6397             status = JAMC_POP_UNEXPECTED;
6398         }
6399     }
6400 
6401     return status;
6402 }
6403 
6404 /****************************************************************************/
6405 /*                                                                          */
6406 
urj_jam_process_pre_post(JAME_INSTRUCTION instruction_code,char * statement_buffer)6407 JAM_RETURN_TYPE urj_jam_process_pre_post
6408     (JAME_INSTRUCTION instruction_code, char *statement_buffer)
6409 /*                                                                          */
6410 /*  Description:    Processes the PREDR, PREIR, POSTDR, and POSTIR          */
6411 /*                  statements.  These statements together replace the      */
6412 /*                  PADDING statement from the JAM 1.0 language spec.       */
6413 /*                                                                          */
6414 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
6415 /*                                                                          */
6416 /****************************************************************************/
6417 {
6418     int index = 0;
6419     int expr_begin = 0;
6420     int expr_end = 0;
6421     int delimiter = 0;
6422     char save_ch = 0;
6423     int32_t count = 0L;
6424     int32_t start_index = 0L;
6425     int32_t stop_index = 0L;
6426     int32_t *literal_array_data = NULL;
6427     int32_t *padding_data = NULL;
6428     JAMS_SYMBOL_RECORD *symbol_record = NULL;
6429     JAMS_HEAP_RECORD *heap_record = NULL;
6430     JAME_EXPRESSION_TYPE expr_type = JAM_ILLEGAL_EXPR_TYPE;
6431     JAM_RETURN_TYPE status = JAMC_SUCCESS;
6432 
6433     if ((urj_jam_version == 2) && (urj_jam_phase != JAM_PROCEDURE_PHASE))
6434     {
6435         return JAMC_PHASE_ERROR;
6436     }
6437 
6438     index = urj_jam_skip_instruction_name (statement_buffer);
6439 
6440     /*
6441      *      First, get the count value
6442      */
6443     status = urj_jam_find_argument (&statement_buffer[index],
6444                                 &expr_begin, &expr_end, &delimiter);
6445 
6446     expr_begin += index;
6447     expr_end += index;
6448     delimiter += index;
6449 
6450     if (status == JAMC_SUCCESS)
6451     {
6452         save_ch = statement_buffer[expr_end];
6453         statement_buffer[expr_end] = JAMC_NULL_CHAR;
6454         status =
6455             urj_jam_evaluate_expression (&statement_buffer[expr_begin], &count,
6456                                      &expr_type);
6457         statement_buffer[expr_end] = save_ch;
6458 
6459         /*
6460          *      Check for integer expression
6461          */
6462         if ((status == JAMC_SUCCESS) &&
6463             (expr_type != JAM_INTEGER_EXPR) &&
6464             (expr_type != JAM_INT_OR_BOOL_EXPR))
6465         {
6466             status = JAMC_TYPE_MISMATCH;
6467         }
6468 
6469         /*
6470          *      Check the range -- count value must be between 0 and 1000
6471          */
6472         if ((status == JAMC_SUCCESS) && ((count < 0L) || (count > 1000L)))
6473         {
6474             status = JAMC_SYNTAX_ERROR;
6475         }
6476     }
6477 
6478     /*
6479      *      Second, get the optional padding data pattern (Boolean array)
6480      */
6481     if (status == JAMC_SUCCESS)
6482     {
6483         if (statement_buffer[delimiter] == JAMC_COMMA_CHAR)
6484         {
6485             expr_begin = delimiter + 1;
6486             expr_end = expr_begin;
6487             while ((isspace (statement_buffer[expr_begin])) &&
6488                    (expr_begin < JAMC_MAX_STATEMENT_LENGTH))
6489             {
6490                 ++expr_begin;   /* skip over white space */
6491             }
6492             while ((statement_buffer[expr_end] != JAMC_NULL_CHAR) &&
6493                    (expr_end < JAMC_MAX_STATEMENT_LENGTH))
6494             {
6495                 ++expr_end;
6496             }
6497             while ((statement_buffer[expr_end] != JAMC_SEMICOLON_CHAR) &&
6498                    (expr_end > 0))
6499             {
6500                 --expr_end;
6501             }
6502 
6503             if (expr_end > expr_begin)
6504             {
6505                 save_ch = statement_buffer[expr_end];
6506                 statement_buffer[expr_end] = JAMC_NULL_CHAR;
6507                 status =
6508                     urj_jam_get_array_argument (&statement_buffer[expr_begin],
6509                                             &symbol_record,
6510                                             &literal_array_data, &start_index,
6511                                             &stop_index, 0);
6512                 statement_buffer[expr_end] = save_ch;
6513 
6514                 if ((status == JAMC_SUCCESS) &&
6515                     (stop_index < (start_index + count - 1)))
6516                 {
6517                     status = JAMC_BOUNDS_ERROR;
6518                 }
6519 
6520                 if (status == JAMC_SUCCESS)
6521                 {
6522                     if (symbol_record != NULL)
6523                     {
6524                         heap_record =
6525                             (JAMS_HEAP_RECORD *) symbol_record->value;
6526 
6527                         if (heap_record != NULL)
6528                         {
6529                             padding_data = heap_record->data;
6530                         }
6531                         else
6532                         {
6533                             status = JAMC_INTERNAL_ERROR;
6534                         }
6535                     }
6536                     else if (literal_array_data != NULL)
6537                     {
6538                         padding_data = literal_array_data;
6539                     }
6540                     else
6541                     {
6542                         status = JAMC_INTERNAL_ERROR;
6543                     }
6544                 }
6545             }
6546             else
6547             {
6548                 status = JAMC_SYNTAX_ERROR;
6549             }
6550         }
6551         else if (statement_buffer[delimiter] != JAMC_SEMICOLON_CHAR)
6552         {
6553             status = JAMC_SYNTAX_ERROR;
6554         }
6555     }
6556 
6557     /*
6558      *      Store the new padding value
6559      */
6560     if (status == JAMC_SUCCESS)
6561     {
6562         switch (instruction_code)
6563         {
6564         case JAM_POSTDR_INSTR:
6565             status = urj_jam_set_dr_postamble ((int) count, (int) start_index,
6566                                            padding_data);
6567             break;
6568 
6569         case JAM_POSTIR_INSTR:
6570             status = urj_jam_set_ir_postamble ((int) count, (int) start_index,
6571                                            padding_data);
6572             break;
6573 
6574         case JAM_PREDR_INSTR:
6575             status = urj_jam_set_dr_preamble ((int) count, (int) start_index,
6576                                           padding_data);
6577             break;
6578 
6579         case JAM_PREIR_INSTR:
6580             status = urj_jam_set_ir_preamble ((int) count, (int) start_index,
6581                                           padding_data);
6582             break;
6583 
6584         default:
6585             status = JAMC_INTERNAL_ERROR;
6586             break;
6587         }
6588     }
6589 
6590     return status;
6591 }
6592 
6593 /****************************************************************************/
6594 /*                                                                          */
6595 
6596 JAM_RETURN_TYPE
urj_jam_process_print(char * statement_buffer)6597 urj_jam_process_print (char *statement_buffer)
6598 /*                                                                          */
6599 /*  Description:    Processes a PRINT statement.  Only constant literal     */
6600 /*                  strings and INTEGER or BOOLEAN expressions are          */
6601 /*                  supported.                                              */
6602 /*                                                                          */
6603 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
6604 /*                                                                          */
6605 /****************************************************************************/
6606 {
6607     int index = 0;
6608     int dest_index = 0;
6609     char *text_buffer = NULL;
6610     int expr_begin = 0;
6611     int expr_end = 0;
6612     char save_ch = 0;
6613     int32_t expr_value = 0L;
6614     JAM_RETURN_TYPE status = JAMC_SUCCESS;
6615 
6616     if ((urj_jam_version == 2) && (urj_jam_phase != JAM_PROCEDURE_PHASE))
6617     {
6618         return JAMC_PHASE_ERROR;
6619     }
6620 
6621     text_buffer = malloc (JAMC_MAX_STATEMENT_LENGTH + 1024);
6622 
6623     if (text_buffer == NULL)
6624     {
6625         status = JAMC_OUT_OF_MEMORY;
6626     }
6627     else
6628     {
6629         index = urj_jam_skip_instruction_name (statement_buffer);
6630     }
6631 
6632     while ((status == JAMC_SUCCESS) &&
6633            (statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
6634            (index < JAMC_MAX_STATEMENT_LENGTH))
6635     {
6636         /*
6637          *      Get arguments from statement and concatenate onto string
6638          */
6639         if (statement_buffer[index] == JAMC_QUOTE_CHAR)
6640         {
6641             /*
6642              *      Argument is explicit string - copy it
6643              */
6644             ++index;
6645             while ((statement_buffer[index] != JAMC_QUOTE_CHAR) &&
6646                    (index < JAMC_MAX_STATEMENT_LENGTH) &&
6647                    (dest_index < JAMC_MAX_STATEMENT_LENGTH))
6648             {
6649                 text_buffer[dest_index++] = statement_buffer[index++];
6650             }
6651             text_buffer[dest_index] = '\0';
6652 
6653             if (statement_buffer[index] == JAMC_QUOTE_CHAR)
6654             {
6655                 /* skip over terminating quote character */
6656                 ++index;
6657             }
6658             else
6659             {
6660                 /* terminating quote character not found */
6661                 status = JAMC_SYNTAX_ERROR;
6662             }
6663         }
6664         else if ((statement_buffer[index] == 'C') &&
6665                  (statement_buffer[index + 1] == 'H') &&
6666                  (statement_buffer[index + 2] == 'R') &&
6667                  (statement_buffer[index + 3] == JAMC_DOLLAR_CHAR) &&
6668                  (statement_buffer[index + 4] == JAMC_LPAREN_CHAR))
6669         {
6670             /*
6671              *      Convert integer expression to character code
6672              */
6673             index += 4;         /* skip over CHR$, point to left parenthesis */
6674             expr_begin = index;
6675             expr_end = 0;
6676 
6677             while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
6678                    (statement_buffer[index] != JAMC_COMMA_CHAR) &&
6679                    (statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
6680                    (index < JAMC_MAX_STATEMENT_LENGTH))
6681             {
6682                 ++index;
6683             }
6684 
6685             if ((statement_buffer[index] == JAMC_COMMA_CHAR) ||
6686                 (statement_buffer[index] == JAMC_SEMICOLON_CHAR))
6687             {
6688                 expr_end = index;
6689             }
6690 
6691             if (expr_end > expr_begin)
6692             {
6693                 save_ch = statement_buffer[expr_end];
6694                 statement_buffer[expr_end] = JAMC_NULL_CHAR;
6695                 status =
6696                     urj_jam_evaluate_expression (&statement_buffer[expr_begin],
6697                                              &expr_value, NULL);
6698                 statement_buffer[expr_end] = save_ch;
6699             }
6700             else
6701             {
6702                 status = JAMC_SYNTAX_ERROR;
6703             }
6704 
6705             /*
6706              *      Allow any seven-bit character code (zero to 127)
6707              */
6708             if ((status == JAMC_SUCCESS) &&
6709                 ((expr_value < 0) || (expr_value > 127)))
6710             {
6711                 /* character code out of range */
6712 
6713                 /* instead of flagging an error, force the value to 127 */
6714                 expr_value = 127;
6715             }
6716 
6717             if ((status == JAMC_SUCCESS) &&
6718                 (dest_index >= JAMC_MAX_STATEMENT_LENGTH))
6719             {
6720                 /* no space in output buffer */
6721                 status = JAMC_SYNTAX_ERROR;
6722             }
6723 
6724             if (status == JAMC_SUCCESS)
6725             {
6726                 /*
6727                  *      Put the character code directly into the output buffer
6728                  */
6729                 text_buffer[dest_index++] = (char) expr_value;
6730                 text_buffer[dest_index] = '\0';
6731             }
6732         }
6733         else
6734         {
6735             /*
6736              *      Process it as an integer expression
6737              */
6738             expr_begin = index;
6739             expr_end = 0;
6740             status = JAMC_SYNTAX_ERROR;
6741 
6742             while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
6743                    (statement_buffer[index] != JAMC_COMMA_CHAR) &&
6744                    (statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
6745                    (index < JAMC_MAX_STATEMENT_LENGTH))
6746             {
6747                 ++index;
6748             }
6749 
6750             if ((statement_buffer[index] == JAMC_COMMA_CHAR) ||
6751                 (statement_buffer[index] == JAMC_SEMICOLON_CHAR))
6752             {
6753                 expr_end = index;
6754             }
6755 
6756             if (expr_end > expr_begin)
6757             {
6758                 save_ch = statement_buffer[expr_end];
6759                 statement_buffer[expr_end] = JAMC_NULL_CHAR;
6760                 status =
6761                     urj_jam_evaluate_expression (&statement_buffer[expr_begin],
6762                                              &expr_value, NULL);
6763                 statement_buffer[expr_end] = save_ch;
6764             }
6765 
6766             if (status == JAMC_SUCCESS)
6767             {
6768                 /*
6769                  *      Convert integer and concatenate to output string
6770                  */
6771                 jam_ltoa (&text_buffer[dest_index], expr_value);
6772 
6773                 /* advance pointer to new end of string */
6774                 while ((text_buffer[dest_index] != JAMC_NULL_CHAR) &&
6775                        (dest_index < JAMC_MAX_STATEMENT_LENGTH))
6776                 {
6777                     ++dest_index;
6778                 }
6779             }
6780         }
6781 
6782         if (status == JAMC_SUCCESS)
6783         {
6784             while ((isspace (statement_buffer[index])) &&
6785                    (index < JAMC_MAX_STATEMENT_LENGTH))
6786             {
6787                 ++index;        /* skip over white space */
6788             }
6789 
6790             if (statement_buffer[index] == JAMC_COMMA_CHAR)
6791             {
6792                 /*
6793                  *      Skip over comma and white space to process next argument
6794                  */
6795                 ++index;
6796                 while ((isspace (statement_buffer[index])) &&
6797                        (index < JAMC_MAX_STATEMENT_LENGTH))
6798                 {
6799                     ++index;    /* skip over white space */
6800                 }
6801             }
6802             else if (statement_buffer[index] != JAMC_SEMICOLON_CHAR)
6803             {
6804                 /*
6805                  *      If no comma to seperate arguments, statement must be
6806                  *      terminated by a semicolon
6807                  */
6808                 status = JAMC_SYNTAX_ERROR;
6809             }
6810         }
6811     }
6812 
6813     if (status == JAMC_SUCCESS)
6814     {
6815         urj_jam_message (text_buffer);
6816     }
6817 
6818     if (text_buffer != NULL)
6819         free (text_buffer);
6820 
6821     return status;
6822 }
6823 
6824 /****************************************************************************/
6825 /*                                                                          */
6826 
6827 JAM_RETURN_TYPE
urj_jam_process_procedure(char * statement_buffer)6828 urj_jam_process_procedure (char *statement_buffer)
6829 /*                                                                          */
6830 /*  Description:    Initializes a procedure block.  This function does not  */
6831 /*                  actually execute the procedure, it merely adds it to    */
6832 /*                  the symbol table so it may be executed later.           */
6833 /*                                                                          */
6834 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
6835 /*                                                                          */
6836 /****************************************************************************/
6837 {
6838     int index = 0;
6839     int procname_begin = 0;
6840     int procname_end = 0;
6841     char save_ch = 0;
6842     JAM_RETURN_TYPE status = JAMC_SUCCESS;
6843     JAMS_SYMBOL_RECORD *symbol_record = NULL;
6844     JAMS_HEAP_RECORD *heap_record = NULL;
6845 
6846     if (urj_jam_version == 0)
6847         urj_jam_version = 2;
6848 
6849     if (urj_jam_version == 1)
6850         status = JAMC_SYNTAX_ERROR;
6851 
6852     if ((urj_jam_version == 2) && (urj_jam_phase != JAM_PROCEDURE_PHASE))
6853     {
6854         status = JAMC_PHASE_ERROR;
6855     }
6856 
6857     if ((urj_jam_version == 2) && (urj_jam_phase == JAM_ACTION_PHASE))
6858     {
6859         status = JAMC_ACTION_NOT_FOUND;
6860     }
6861 
6862     if (status == JAMC_SUCCESS)
6863     {
6864         index = urj_jam_skip_instruction_name (statement_buffer);
6865 
6866         if (isalpha (statement_buffer[index]))
6867         {
6868             /*
6869              *      Get the procedure name
6870              */
6871             procname_begin = index;
6872             while ((jam_is_name_char (statement_buffer[index])) &&
6873                    (index < JAMC_MAX_STATEMENT_LENGTH))
6874             {
6875                 ++index;        /* skip over procedure name */
6876             }
6877             procname_end = index;
6878 
6879             save_ch = statement_buffer[procname_end];
6880             statement_buffer[procname_end] = JAMC_NULL_CHAR;
6881             status = urj_jam_add_symbol (JAM_PROCEDURE_BLOCK,
6882                                      &statement_buffer[procname_begin], 0L,
6883                                      urj_jam_current_statement_position);
6884             /* get a pointer to the symbol record */
6885             if (status == JAMC_SUCCESS)
6886             {
6887                 status =
6888                     urj_jam_get_symbol_record (&statement_buffer[procname_begin],
6889                                            &symbol_record);
6890             }
6891             statement_buffer[procname_end] = save_ch;
6892 
6893             while ((isspace (statement_buffer[index])) &&
6894                    (index < JAMC_MAX_STATEMENT_LENGTH))
6895             {
6896                 ++index;        /* skip over white space */
6897             }
6898         }
6899         else
6900         {
6901             status = JAMC_SYNTAX_ERROR;
6902         }
6903     }
6904 
6905     if (status == JAMC_SUCCESS)
6906     {
6907         /*
6908          *      Get list of USES blocks
6909          */
6910         if (statement_buffer[index] != JAMC_SEMICOLON_CHAR)
6911         {
6912             if ((strncmp (&statement_buffer[index], "USES", 4) == 0) &&
6913                 (isspace (statement_buffer[index + 4])))
6914             {
6915                 /*
6916                  *      Get list of USES blocks
6917                  */
6918                 index += 4;     /* skip over USES keyword */
6919 
6920                 while ((isspace (statement_buffer[index])) &&
6921                        (index < JAMC_MAX_STATEMENT_LENGTH))
6922                 {
6923                     ++index;    /* skip over white space */
6924                 }
6925 
6926                 if (symbol_record->value == 0)
6927                 {
6928                     status = urj_jam_add_heap_record (symbol_record, &heap_record,
6929                                                   strlen
6930                                                   (&statement_buffer[index]) +
6931                                                   1);
6932 
6933                     if (status == JAMC_SUCCESS)
6934                     {
6935                         symbol_record->value = (int32_t) heap_record;
6936                         strcpy ((char *) heap_record->data,
6937                                     &statement_buffer[index]);
6938                     }
6939                 }
6940                 else
6941                 {
6942                     heap_record = (JAMS_HEAP_RECORD *) symbol_record->value;
6943                 }
6944 
6945                 /*
6946                  *      Ignore the USES clause -- it will be processed later
6947                  */
6948                 while ((statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
6949                        (statement_buffer[index] != JAMC_NULL_CHAR) &&
6950                        (index < JAMC_MAX_STATEMENT_LENGTH))
6951                 {
6952                     ++index;
6953                 }
6954             }
6955             else
6956             {
6957                 /* error: expected USES keyword */
6958                 status = JAMC_SYNTAX_ERROR;
6959             }
6960         }
6961     }
6962 
6963     return status;
6964 }
6965 
6966 /****************************************************************************/
6967 /*                                                                          */
6968 
6969 JAM_RETURN_TYPE
urj_jam_process_push(char * statement_buffer)6970 urj_jam_process_push (char *statement_buffer)
6971 /*                                                                          */
6972 /*  Description:    Pushes an integer or Boolean value onto the stack       */
6973 /*                                                                          */
6974 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
6975 /*                                                                          */
6976 /****************************************************************************/
6977 {
6978     int index = 0;
6979     int expr_begin = 0;
6980     int expr_end = 0;
6981     char save_ch = 0;
6982     int32_t push_value = 0L;
6983     JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
6984 
6985     if ((urj_jam_version == 2) && (urj_jam_phase != JAM_PROCEDURE_PHASE))
6986     {
6987         return JAMC_PHASE_ERROR;
6988     }
6989 
6990     index = urj_jam_skip_instruction_name (statement_buffer);
6991 
6992     /*
6993      *      Evaluate expression for the PUSH value
6994      */
6995     expr_begin = index;
6996     while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
6997            (index < JAMC_MAX_STATEMENT_LENGTH))
6998     {
6999         ++index;
7000     }
7001     while ((statement_buffer[index] != JAMC_SEMICOLON_CHAR) && (index > 0))
7002     {
7003         --index;
7004     }
7005     expr_end = index;
7006 
7007     if (expr_end > expr_begin)
7008     {
7009         save_ch = statement_buffer[expr_end];
7010         statement_buffer[expr_end] = JAMC_NULL_CHAR;
7011         status =
7012             urj_jam_evaluate_expression (&statement_buffer[expr_begin],
7013                                      &push_value, NULL);
7014         statement_buffer[expr_end] = save_ch;
7015     }
7016 
7017     /*
7018      *      Push the value onto the stack
7019      */
7020     if (status == JAMC_SUCCESS)
7021     {
7022         status = urj_jam_push_pushpop_record (push_value);
7023     }
7024 
7025     return status;
7026 }
7027 
7028 /****************************************************************************/
7029 /*                                                                          */
7030 
7031 JAM_RETURN_TYPE
urj_jam_process_return(char * statement_buffer,BOOL endproc)7032 urj_jam_process_return (char *statement_buffer, BOOL endproc)
7033 /*                                                                          */
7034 /*  Description:    Returns from subroutine by popping the return address   */
7035 /*                  off the stack                                           */
7036 /*                                                                          */
7037 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
7038 /*                                                                          */
7039 /****************************************************************************/
7040 {
7041     int index = 0;
7042     int32_t return_position = 0L;
7043     JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
7044     JAMS_STACK_RECORD *stack_record = NULL;
7045 
7046     if ((urj_jam_version == 0) && endproc)
7047         urj_jam_version = 2;
7048 
7049     if ((urj_jam_version == 0) && !endproc)
7050         urj_jam_version = 1;
7051 
7052     if ((urj_jam_version == 2) && !endproc)
7053     {
7054         /* Jam 2.0 does not support the RETURN statement */
7055         return JAMC_SYNTAX_ERROR;
7056     }
7057 
7058     index = urj_jam_skip_instruction_name (statement_buffer);
7059 
7060     /*
7061      *      The semicolon must be next.
7062      */
7063     if (statement_buffer[index] == JAMC_SEMICOLON_CHAR)
7064     {
7065         /*
7066          *      Get stack record at top of stack
7067          */
7068         stack_record = urj_jam_peek_stack_record ();
7069 
7070         /*
7071          *      Check that stack record corresponds to a CALL statement
7072          */
7073         if ((stack_record != NULL) &&
7074             (stack_record->type == JAM_STACK_CALL_RETURN))
7075         {
7076             /*
7077              *      Stack record is the correct type -- pop it off the stack.
7078              */
7079             return_position = stack_record->return_position;
7080             status = urj_jam_pop_stack_record ();
7081 
7082             /*
7083              *      Now jump to the return address
7084              */
7085             if (status == JAMC_SUCCESS)
7086             {
7087                 if (urj_jam_seek (return_position) == 0)
7088                 {
7089                     urj_jam_current_file_position = return_position;
7090                 }
7091                 else
7092                 {
7093                     /* seek failed */
7094                     status = JAMC_IO_ERROR;
7095                 }
7096             }
7097         }
7098         else
7099         {
7100             status = JAMC_RETURN_UNEXPECTED;
7101         }
7102     }
7103 
7104     return status;
7105 }
7106 
7107 /****************************************************************************/
7108 /*                                                                          */
7109 
urj_jam_find_state_argument(char * statement_buffer,int * begin,int * end,int * delimiter)7110 JAM_RETURN_TYPE urj_jam_find_state_argument
7111     (char *statement_buffer, int *begin, int *end, int *delimiter)
7112 /*                                                                          */
7113 /*  Description:    Special version of urj_jam_find_argument() for state paths. */
7114 /*                  Valid delimiters are whitespace, COMMA, or SEMICOLON.   */
7115 /*                  Returns indices of begin and end of argument, and the   */
7116 /*                  delimiter after the argument.                           */
7117 /*                                                                          */
7118 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
7119 /*                                                                          */
7120 /****************************************************************************/
7121 {
7122     int index = 0;
7123     JAM_RETURN_TYPE status = JAMC_SUCCESS;
7124 
7125     while ((isspace (statement_buffer[index])) &&
7126            (index < JAMC_MAX_STATEMENT_LENGTH))
7127     {
7128         ++index;                /* skip over white space */
7129     }
7130 
7131     *begin = index;
7132 
7133     /* loop until white space or comma or semicolon */
7134     while ((!isspace (statement_buffer[index])) &&
7135            (statement_buffer[index] != JAMC_NULL_CHAR) &&
7136            (statement_buffer[index] != JAMC_COMMA_CHAR) &&
7137            (statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
7138            (index < JAMC_MAX_STATEMENT_LENGTH))
7139     {
7140         ++index;
7141     }
7142 
7143     if ((!isspace (statement_buffer[index])) &&
7144         (statement_buffer[index] != JAMC_COMMA_CHAR) &&
7145         (statement_buffer[index] != JAMC_SEMICOLON_CHAR))
7146     {
7147         status = JAMC_SYNTAX_ERROR;
7148     }
7149     else
7150     {
7151         *end = index;           /* end is position after last argument character */
7152 
7153         *delimiter = index;     /* delimiter is position of comma or semicolon */
7154 
7155         /* check whether a comma or semicolon comes after the white space */
7156         while ((isspace (statement_buffer[index])) &&
7157                (statement_buffer[index] != JAMC_NULL_CHAR) &&
7158                (index < JAMC_MAX_STATEMENT_LENGTH))
7159         {
7160             ++index;
7161         }
7162 
7163         if ((statement_buffer[index] == JAMC_COMMA_CHAR) ||
7164             (statement_buffer[index] == JAMC_SEMICOLON_CHAR))
7165         {
7166             *delimiter = index; /* send the real delimiter */
7167         }
7168 
7169     }
7170 
7171     return status;
7172 }
7173 
7174 /****************************************************************************/
7175 /*                                                                          */
7176 
7177 JAM_RETURN_TYPE
urj_jam_process_state(char * statement_buffer)7178 urj_jam_process_state (char *statement_buffer)
7179 /*                                                                          */
7180 /*  Description:    Forces JTAG chain to specified state, or through        */
7181 /*                  specified sequence of states                            */
7182 /*                                                                          */
7183 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
7184 /*                                                                          */
7185 /****************************************************************************/
7186 {
7187     int index = 0;
7188     int expr_begin = 0;
7189     int expr_end = 0;
7190     int delimiter = 0;
7191     char save_ch = 0;
7192     JAM_RETURN_TYPE status = JAMC_SUCCESS;
7193     JAME_JTAG_STATE state = JAM_ILLEGAL_JTAG_STATE;
7194 
7195     if ((urj_jam_version == 2) && (urj_jam_phase != JAM_PROCEDURE_PHASE))
7196     {
7197         return JAMC_PHASE_ERROR;
7198     }
7199 
7200     index = urj_jam_skip_instruction_name (statement_buffer);
7201 
7202     do
7203     {
7204         /*
7205          *      Get next argument
7206          */
7207         status = urj_jam_find_state_argument (&statement_buffer[index],
7208                                           &expr_begin, &expr_end, &delimiter);
7209 
7210         if (status == JAMC_SUCCESS)
7211         {
7212             expr_begin += index;
7213             expr_end += index;
7214             delimiter += index;
7215 
7216             save_ch = statement_buffer[expr_end];
7217             statement_buffer[expr_end] = JAMC_NULL_CHAR;
7218             state =
7219                 urj_jam_get_jtag_state_from_name (&statement_buffer[expr_begin]);
7220 
7221             if (state == JAM_ILLEGAL_JTAG_STATE)
7222             {
7223                 status = JAMC_SYNTAX_ERROR;
7224             }
7225             else
7226             {
7227                 /*
7228                  *      Go to the specified state
7229                  */
7230                 status = urj_jam_goto_jtag_state (state);
7231                 index = delimiter + 1;
7232             }
7233 
7234             statement_buffer[expr_end] = save_ch;
7235         }
7236     }
7237     while ((status == JAMC_SUCCESS) &&
7238            ((isspace (statement_buffer[delimiter])) ||
7239             (statement_buffer[delimiter] == JAMC_COMMA_CHAR)));
7240 
7241     if ((status == JAMC_SUCCESS) &&
7242         (statement_buffer[delimiter] != JAMC_SEMICOLON_CHAR))
7243     {
7244         status = JAMC_SYNTAX_ERROR;
7245     }
7246 
7247     return status;
7248 }
7249 
7250 /****************************************************************************/
7251 /*                                                                          */
7252 
7253 JAM_RETURN_TYPE
urj_jam_process_trst(char * statement_buffer)7254 urj_jam_process_trst (char *statement_buffer)
7255 /*                                                                          */
7256 /*  Description:    Asserts the TRST signal to the JTAG hardware interface. */
7257 /*                  NOTE: this does not guarantee a chain reset, because    */
7258 /*                  some devices in the chain may not use the TRST signal.  */
7259 /*                                                                          */
7260 /*                  TRST <integer-expr> CYCLES;     -or-                    */
7261 /*                  TRST <integer-expr> USEC;       -or-                    */
7262 /*                  TRST <integer-expr> CYCLES, <integer-expr> USEC;        */
7263 /*                                                                          */
7264 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
7265 /*                                                                          */
7266 /****************************************************************************/
7267 {
7268     JAM_RETURN_TYPE status = JAMC_SUCCESS;
7269 
7270     if (urj_jam_version == 0)
7271         urj_jam_version = 2;
7272 
7273     if (urj_jam_version == 1)
7274         status = JAMC_SYNTAX_ERROR;
7275 
7276     if ((urj_jam_version == 2) && (urj_jam_phase != JAM_PROCEDURE_PHASE))
7277     {
7278         status = JAMC_PHASE_ERROR;
7279     }
7280 
7281     /* assert TRST...  NOT IMPLEMENTED YET! */
7282 
7283     status = urj_jam_process_wait (statement_buffer);
7284 
7285     /* release TRST...  NOT IMPLEMENTED YET! */
7286 
7287     return status;
7288 }
7289 
7290 /****************************************************************************/
7291 /*                                                                          */
7292 
urj_jam_process_vector_capture(char * statement_buffer,int signal_count,int32_t * dir_vector,int32_t * data_vector)7293 JAM_RETURN_TYPE urj_jam_process_vector_capture
7294     (char *statement_buffer,
7295      int signal_count, int32_t *dir_vector, int32_t *data_vector)
7296 /*                                                                          */
7297 /*  Description:    Applies signals to non-JTAG hardware interface, reads   */
7298 /*                  back signals from hardware, and stores values in the    */
7299 /*                  capture array.  The syntax for the entire statement is: */
7300 /*                                                                          */
7301 /*                  VECTOR <dir>, <data>, CAPTURE <capture> ;               */
7302 /*                                                                          */
7303 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
7304 /*                                                                          */
7305 /****************************************************************************/
7306 {
7307     int expr_begin = 0;
7308     int expr_end = 0;
7309     int delimiter = 0;
7310     int32_t start_index = 0L;
7311     int32_t stop_index = 0L;
7312     char save_ch = 0;
7313     int32_t *literal_array_data = NULL;
7314     JAMS_SYMBOL_RECORD *symbol_record = NULL;
7315     JAMS_HEAP_RECORD *heap_record = NULL;
7316     JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
7317 
7318     /*
7319      *      Statement buffer should contain the part of the statement string
7320      *      after the CAPTURE keyword.
7321      *
7322      *      The only argument should be the capture array.
7323      */
7324     status = urj_jam_find_argument (statement_buffer,
7325                                 &expr_begin, &expr_end, &delimiter);
7326 
7327     if ((status == JAMC_SUCCESS) &&
7328         (statement_buffer[delimiter] != JAMC_SEMICOLON_CHAR))
7329     {
7330         status = JAMC_SYNTAX_ERROR;
7331     }
7332 
7333     if (status == JAMC_SUCCESS)
7334     {
7335         save_ch = statement_buffer[expr_end];
7336         statement_buffer[expr_end] = JAMC_NULL_CHAR;
7337         status = urj_jam_get_array_argument (&statement_buffer[expr_begin],
7338                                          &symbol_record, &literal_array_data,
7339                                          &start_index, &stop_index, 2);
7340         statement_buffer[expr_end] = save_ch;
7341     }
7342 
7343     if ((status == JAMC_SUCCESS) && (literal_array_data != NULL))
7344     {
7345         /* literal array may not be used for capture buffer */
7346         status = JAMC_SYNTAX_ERROR;
7347     }
7348 
7349     if ((status == JAMC_SUCCESS) &&
7350         (stop_index != start_index + signal_count - 1))
7351     {
7352         status = JAMC_BOUNDS_ERROR;
7353     }
7354 
7355     if (status == JAMC_SUCCESS)
7356     {
7357         if (symbol_record != NULL)
7358         {
7359             heap_record = (JAMS_HEAP_RECORD *) symbol_record->value;
7360 
7361             if (!heap_record)
7362                 status = JAMC_INTERNAL_ERROR;
7363         }
7364         else
7365             status = JAMC_INTERNAL_ERROR;
7366     }
7367 
7368     /*
7369      *      Perform the VECTOR operation, capturing data into the heap buffer
7370      */
7371     if (status == JAMC_SUCCESS)
7372     {
7373         //if (jam_vector_io (signal_count, dir_vector, data_vector,
7374         //                   capture_buffer) != signal_count)
7375         {
7376             status = JAMC_INTERNAL_ERROR;
7377         }
7378     }
7379 
7380     return status;
7381 }
7382 
7383 /****************************************************************************/
7384 /*                                                                          */
7385 
urj_jam_process_vector_compare(char * statement_buffer,int signal_count,int32_t * dir_vector,int32_t * data_vector)7386 JAM_RETURN_TYPE urj_jam_process_vector_compare
7387     (char *statement_buffer,
7388      int signal_count, int32_t *dir_vector, int32_t *data_vector)
7389 /*                                                                          */
7390 /*  Description:    Applies signals to non-JTAG hardware interface, reads   */
7391 /*                  back signals from hardware, and compares values to the  */
7392 /*                  expected values.  Result is stored in a BOOLEAN         */
7393 /*                  variable.  The syntax for the entire statement is:      */
7394 /*                                                                          */
7395 /*          VECTOR <dir>, <data>, COMPARE <expected>, <mask>, <result> ;    */
7396 /*                                                                          */
7397 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
7398 /*                                                                          */
7399 /****************************************************************************/
7400 {
7401     int bit = 0;
7402     int index = 0;
7403     int expr_begin = 0;
7404     int expr_end = 0;
7405     int delimiter = 0;
7406     int actual = 0;
7407     int expected = 0;
7408     int mask = 0;
7409     int32_t comp_start_index = 0L;
7410     int32_t comp_stop_index = 0L;
7411     int32_t mask_start_index = 0L;
7412     int32_t mask_stop_index = 0L;
7413     char save_ch = 0;
7414     int32_t *temp_array = NULL;
7415     BOOL result = true;
7416     JAMS_SYMBOL_RECORD *symbol_record = NULL;
7417     JAMS_HEAP_RECORD *heap_record = NULL;
7418     int32_t *comp_data = NULL;
7419     int32_t *mask_data = NULL;
7420     int32_t *literal_array_data = NULL;
7421     JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
7422 
7423     /*
7424      *      Statement buffer should contain the part of the statement string
7425      *      after the COMPARE keyword.
7426      *
7427      *      The first argument should be the compare array.
7428      */
7429     status = urj_jam_find_argument (statement_buffer,
7430                                 &expr_begin, &expr_end, &delimiter);
7431 
7432     if ((status == JAMC_SUCCESS) &&
7433         (statement_buffer[delimiter] != JAMC_COMMA_CHAR))
7434     {
7435         status = JAMC_SYNTAX_ERROR;
7436     }
7437 
7438     if (status == JAMC_SUCCESS)
7439     {
7440         save_ch = statement_buffer[expr_end];
7441         statement_buffer[expr_end] = JAMC_NULL_CHAR;
7442         status = urj_jam_get_array_argument (&statement_buffer[expr_begin],
7443                                          &symbol_record, &literal_array_data,
7444                                          &comp_start_index, &comp_stop_index,
7445                                          2);
7446         statement_buffer[expr_end] = save_ch;
7447         index = delimiter + 1;
7448     }
7449 
7450     if ((status == JAMC_SUCCESS) &&
7451         (literal_array_data != NULL) &&
7452         (comp_start_index == 0) && (comp_stop_index > signal_count - 1))
7453     {
7454         comp_stop_index = signal_count - 1;
7455     }
7456 
7457     if ((status == JAMC_SUCCESS) &&
7458         (comp_stop_index != comp_start_index + signal_count - 1))
7459     {
7460         status = JAMC_BOUNDS_ERROR;
7461     }
7462 
7463     if (status == JAMC_SUCCESS)
7464     {
7465         if (symbol_record != NULL)
7466         {
7467             heap_record = (JAMS_HEAP_RECORD *) symbol_record->value;
7468 
7469             if (heap_record != NULL)
7470             {
7471                 comp_data = heap_record->data;
7472             }
7473             else
7474             {
7475                 status = JAMC_INTERNAL_ERROR;
7476             }
7477         }
7478         else if (literal_array_data != NULL)
7479         {
7480             comp_data = literal_array_data;
7481         }
7482         else
7483         {
7484             status = JAMC_INTERNAL_ERROR;
7485         }
7486     }
7487 
7488     /*
7489      *      Find the next argument -- should be the mask array
7490      */
7491     if (status == JAMC_SUCCESS)
7492     {
7493         status = urj_jam_find_argument (&statement_buffer[index],
7494                                     &expr_begin, &expr_end, &delimiter);
7495 
7496         expr_begin += index;
7497         expr_end += index;
7498         delimiter += index;
7499     }
7500 
7501     if ((status == JAMC_SUCCESS) &&
7502         (statement_buffer[delimiter] != JAMC_COMMA_CHAR))
7503     {
7504         status = JAMC_SYNTAX_ERROR;
7505     }
7506 
7507     if (status == JAMC_SUCCESS)
7508     {
7509         save_ch = statement_buffer[expr_end];
7510         statement_buffer[expr_end] = JAMC_NULL_CHAR;
7511         status = urj_jam_get_array_argument (&statement_buffer[expr_begin],
7512                                          &symbol_record, &literal_array_data,
7513                                          &mask_start_index, &mask_stop_index,
7514                                          3);
7515         statement_buffer[expr_end] = save_ch;
7516         index = delimiter + 1;
7517     }
7518 
7519     if ((status == JAMC_SUCCESS) &&
7520         (literal_array_data != NULL) &&
7521         (mask_start_index == 0) && (mask_stop_index > signal_count - 1))
7522     {
7523         mask_stop_index = signal_count - 1;
7524     }
7525 
7526     if ((status == JAMC_SUCCESS) &&
7527         (mask_stop_index != mask_start_index + signal_count - 1))
7528     {
7529         status = JAMC_BOUNDS_ERROR;
7530     }
7531 
7532     if (status == JAMC_SUCCESS)
7533     {
7534         if (symbol_record != NULL)
7535         {
7536             heap_record = (JAMS_HEAP_RECORD *) symbol_record->value;
7537 
7538             if (heap_record != NULL)
7539             {
7540                 mask_data = heap_record->data;
7541             }
7542             else
7543             {
7544                 status = JAMC_INTERNAL_ERROR;
7545             }
7546         }
7547         else if (literal_array_data != NULL)
7548         {
7549             mask_data = literal_array_data;
7550         }
7551         else
7552         {
7553             status = JAMC_INTERNAL_ERROR;
7554         }
7555     }
7556 
7557     /*
7558      *      Find the third argument -- should be the result variable
7559      */
7560     if (status == JAMC_SUCCESS)
7561     {
7562         status = urj_jam_find_argument (&statement_buffer[index],
7563                                     &expr_begin, &expr_end, &delimiter);
7564 
7565         expr_begin += index;
7566         expr_end += index;
7567         delimiter += index;
7568     }
7569 
7570     if ((status == JAMC_SUCCESS) &&
7571         (statement_buffer[delimiter] != JAMC_SEMICOLON_CHAR))
7572     {
7573         status = JAMC_SYNTAX_ERROR;
7574     }
7575 
7576     /*
7577      *      Result must be a scalar Boolean variable
7578      */
7579     if (status == JAMC_SUCCESS)
7580     {
7581         save_ch = statement_buffer[expr_end];
7582         statement_buffer[expr_end] = JAMC_NULL_CHAR;
7583         status = urj_jam_get_symbol_record (&statement_buffer[expr_begin],
7584                                         &symbol_record);
7585         statement_buffer[expr_end] = save_ch;
7586 
7587         if ((status == JAMC_SUCCESS) &&
7588             (symbol_record->type != JAM_BOOLEAN_SYMBOL))
7589         {
7590             status = JAMC_TYPE_MISMATCH;
7591         }
7592     }
7593 
7594     /*
7595      *      Find some free memory on the heap
7596      */
7597     if (status == JAMC_SUCCESS)
7598     {
7599         temp_array = urj_jam_get_temp_workspace ((signal_count >> 3) + 4);
7600 
7601         if (temp_array == NULL)
7602         {
7603             status = JAMC_OUT_OF_MEMORY;
7604         }
7605     }
7606 
7607     /*
7608      *      Do the VECTOR operation, saving the result in temp_array
7609      */
7610     if (status == JAMC_SUCCESS)
7611     {
7612         //if (jam_vector_io (signal_count, dir_vector, data_vector,
7613         //                   temp_array) != signal_count)
7614         {
7615             status = JAMC_INTERNAL_ERROR;
7616         }
7617     }
7618 
7619     /*
7620      *      Mask the data and do the comparison
7621      */
7622     if (status == JAMC_SUCCESS)
7623     {
7624         for (bit = 0; (bit < signal_count) && result; ++bit)
7625         {
7626             actual = temp_array[bit >> 5] & (1L << (bit & 0x1f)) ? 1 : 0;
7627             expected = comp_data[(bit + comp_start_index) >> 5]
7628                 & (1L << ((bit + comp_start_index) & 0x1f)) ? 1 : 0;
7629             mask = mask_data[(bit + mask_start_index) >> 5]
7630                 & (1L << ((bit + mask_start_index) & 0x1f)) ? 1 : 0;
7631 
7632             if ((actual & mask) != (expected & mask))
7633             {
7634                 result = false;
7635             }
7636         }
7637 
7638         symbol_record->value = result ? 1L : 0L;
7639     }
7640 
7641     if (temp_array != NULL)
7642         urj_jam_free_temp_workspace (temp_array);
7643 
7644     return status;
7645 }
7646 
7647 /****************************************************************************/
7648 /*                                                                          */
7649 
7650 JAM_RETURN_TYPE
urj_jam_process_vector(char * statement_buffer)7651 urj_jam_process_vector (char *statement_buffer)
7652 /*                                                                          */
7653 /*  Description:    Applies signals to non-JTAG hardware interface.  There  */
7654 /*                  are three versions:  output only, compare, and capture. */
7655 /*                                                                          */
7656 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
7657 /*                                                                          */
7658 /****************************************************************************/
7659 {
7660     /* syntax:  VECTOR <dir>, <data>; */
7661     /* or:      VECTOR <dir>, <data>, CAPTURE <capture> ; */
7662     /* or:      VECTOR <dir>, <data>, COMPARE <expected>, <mask>, <result> ; */
7663 
7664     int index = 0;
7665     int expr_begin = 0;
7666     int expr_end = 0;
7667     int delimiter = 0;
7668     int32_t dir_start_index = 0L;
7669     int32_t dir_stop_index = 0L;
7670     int32_t data_start_index = 0L;
7671     int32_t data_stop_index = 0L;
7672     char save_ch = 0;
7673     int32_t *dir_vector = NULL;
7674     int32_t *data_vector = NULL;
7675     int32_t *literal_array_data = NULL;
7676     JAMS_SYMBOL_RECORD *symbol_record = NULL;
7677     JAMS_HEAP_RECORD *heap_record = NULL;
7678     JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
7679 
7680     if ((urj_jam_version == 2) && (urj_jam_phase != JAM_PROCEDURE_PHASE))
7681     {
7682         return JAMC_PHASE_ERROR;
7683     }
7684 
7685     index = urj_jam_skip_instruction_name (statement_buffer);
7686 
7687     /*
7688      *      Get direction vector
7689      */
7690     status = urj_jam_find_argument (&statement_buffer[index],
7691                                 &expr_begin, &expr_end, &delimiter);
7692 
7693     expr_begin += index;
7694     expr_end += index;
7695     delimiter += index;
7696 
7697     if ((status == JAMC_SUCCESS) &&
7698         (statement_buffer[delimiter] != JAMC_COMMA_CHAR))
7699     {
7700         status = JAMC_SYNTAX_ERROR;
7701     }
7702 
7703     if (status == JAMC_SUCCESS)
7704     {
7705         save_ch = statement_buffer[expr_end];
7706         statement_buffer[expr_end] = JAMC_NULL_CHAR;
7707         status = urj_jam_get_array_argument (&statement_buffer[expr_begin],
7708                                          &symbol_record, &literal_array_data,
7709                                          &dir_start_index, &dir_stop_index,
7710                                          0);
7711         statement_buffer[expr_end] = save_ch;
7712     }
7713 
7714     if (status == JAMC_SUCCESS)
7715     {
7716         if (symbol_record != NULL)
7717         {
7718             heap_record = (JAMS_HEAP_RECORD *) symbol_record->value;
7719 
7720             if (heap_record != NULL)
7721             {
7722                 dir_vector = heap_record->data;
7723             }
7724             else
7725             {
7726                 status = JAMC_INTERNAL_ERROR;
7727             }
7728         }
7729         else if (literal_array_data != NULL)
7730         {
7731             dir_vector = literal_array_data;
7732         }
7733         else
7734         {
7735             status = JAMC_INTERNAL_ERROR;
7736         }
7737     }
7738 
7739     /*
7740      *      Get data vector
7741      */
7742     if (status == JAMC_SUCCESS)
7743     {
7744         index = delimiter + 1;
7745         status = urj_jam_find_argument (&statement_buffer[index],
7746                                     &expr_begin, &expr_end, &delimiter);
7747 
7748         expr_begin += index;
7749         expr_end += index;
7750         delimiter += index;
7751     }
7752 
7753     if ((status == JAMC_SUCCESS) &&
7754         (statement_buffer[delimiter] != JAMC_COMMA_CHAR) &&
7755         (statement_buffer[delimiter] != JAMC_SEMICOLON_CHAR))
7756     {
7757         status = JAMC_SYNTAX_ERROR;
7758     }
7759 
7760     if (status == JAMC_SUCCESS)
7761     {
7762         save_ch = statement_buffer[expr_end];
7763         statement_buffer[expr_end] = JAMC_NULL_CHAR;
7764         status = urj_jam_get_array_argument (&statement_buffer[expr_begin],
7765                                          &symbol_record, &literal_array_data,
7766                                          &data_start_index, &data_stop_index,
7767                                          1);
7768         statement_buffer[expr_end] = save_ch;
7769     }
7770 
7771     if (status == JAMC_SUCCESS)
7772     {
7773         if (symbol_record != NULL)
7774         {
7775             heap_record = (JAMS_HEAP_RECORD *) symbol_record->value;
7776 
7777             if (heap_record != NULL)
7778             {
7779                 data_vector = heap_record->data;
7780             }
7781             else
7782             {
7783                 status = JAMC_INTERNAL_ERROR;
7784             }
7785         }
7786         else if (literal_array_data != NULL)
7787         {
7788             data_vector = literal_array_data;
7789         }
7790         else
7791         {
7792             status = JAMC_INTERNAL_ERROR;
7793         }
7794     }
7795 
7796     if ((status == JAMC_SUCCESS) &&
7797         (statement_buffer[delimiter] == JAMC_SEMICOLON_CHAR))
7798     {
7799         /*
7800          *      Do a simple VECTOR operation -- no capture or compare
7801          */
7802         //if (jam_vector_io (urj_jam_vector_signal_count,
7803         //                   dir_vector, data_vector,
7804         //                   NULL) != urj_jam_vector_signal_count)
7805         {
7806             status = JAMC_INTERNAL_ERROR;
7807         }
7808     }
7809     else if ((status == JAMC_SUCCESS) &&
7810              (statement_buffer[delimiter] == JAMC_COMMA_CHAR))
7811     {
7812         /*
7813          *      Delimiter was a COMMA, so look for CAPTURE or COMPARE keyword
7814          */
7815         index = delimiter + 1;
7816         while (isspace (statement_buffer[index]))
7817         {
7818             ++index;            /* skip over white space */
7819         }
7820 
7821         if ((strncmp (&statement_buffer[index], "CAPTURE", 7) == 0) &&
7822             (isspace (statement_buffer[index + 7])))
7823         {
7824             /*
7825              *      Do a VECTOR with capture
7826              */
7827             status = urj_jam_process_vector_capture (&statement_buffer[index + 8],
7828                                                  urj_jam_vector_signal_count,
7829                                                  dir_vector, data_vector);
7830         }
7831         else if ((strncmp (&statement_buffer[index], "COMPARE", 7) == 0)
7832                  && (isspace (statement_buffer[index + 7])))
7833         {
7834             /*
7835              *      Do a VECTOR with compare
7836              */
7837             status = urj_jam_process_vector_compare (&statement_buffer[index + 8],
7838                                                  urj_jam_vector_signal_count,
7839                                                  dir_vector, data_vector);
7840         }
7841         else
7842         {
7843             status = JAMC_SYNTAX_ERROR;
7844         }
7845     }
7846 
7847     return status;
7848 }
7849 
7850 /****************************************************************************/
7851 /*                                                                          */
7852 
7853 #define JAMC_MAX_VECTOR_SIGNALS 256
7854 
7855 JAM_RETURN_TYPE
urj_jam_process_vmap(char * statement_buffer)7856 urj_jam_process_vmap (char *statement_buffer)
7857 /*                                                                          */
7858 /*  Description:    Sets signal mapping for non-JTAG hardware interface.    */
7859 /*                                                                          */
7860 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
7861 /*                                                                          */
7862 /****************************************************************************/
7863 {
7864     int index = 0;
7865     int signal_count = 0;
7866     char *signal_names[JAMC_MAX_VECTOR_SIGNALS];
7867     JAM_RETURN_TYPE status = JAMC_SUCCESS;
7868 
7869     if ((urj_jam_version == 2) && (urj_jam_phase != JAM_PROCEDURE_PHASE))
7870     {
7871         return JAMC_PHASE_ERROR;
7872     }
7873 
7874     index = urj_jam_skip_instruction_name (statement_buffer);
7875 
7876     while ((statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
7877            (status == JAMC_SUCCESS) &&
7878            (index < JAMC_MAX_STATEMENT_LENGTH) &&
7879            (signal_count < JAMC_MAX_VECTOR_SIGNALS))
7880     {
7881         /*
7882          *      Get signal names from statement, add NULL terminination characters,
7883          *      and save a pointer to each name
7884          */
7885         if (statement_buffer[index] == JAMC_QUOTE_CHAR)
7886         {
7887             ++index;
7888             signal_names[signal_count] = &statement_buffer[index];
7889             while ((statement_buffer[index] != JAMC_QUOTE_CHAR) &&
7890                    (index < JAMC_MAX_STATEMENT_LENGTH))
7891             {
7892                 ++index;
7893             }
7894             if (statement_buffer[index] == JAMC_QUOTE_CHAR)
7895             {
7896                 statement_buffer[index] = JAMC_NULL_CHAR;
7897                 ++index;
7898 
7899                 if (*signal_names[signal_count] == JAMC_NULL_CHAR)
7900                 {
7901                     /* check for empty string */
7902                     status = JAMC_SYNTAX_ERROR;
7903                 }
7904                 else
7905                 {
7906                     ++signal_count;
7907                 }
7908             }
7909             else
7910             {
7911                 /* terminating quote character not found */
7912                 status = JAMC_SYNTAX_ERROR;
7913             }
7914         }
7915         else
7916         {
7917             /* argument is not a quoted string */
7918             status = JAMC_SYNTAX_ERROR;
7919         }
7920 
7921         if (status == JAMC_SUCCESS)
7922         {
7923             while ((isspace (statement_buffer[index])) &&
7924                    (index < JAMC_MAX_STATEMENT_LENGTH))
7925             {
7926                 ++index;        /* skip over white space */
7927             }
7928 
7929             if (statement_buffer[index] == JAMC_COMMA_CHAR)
7930             {
7931                 /*
7932                  *      Skip over comma and white space to process next argument
7933                  */
7934                 ++index;
7935                 while ((isspace (statement_buffer[index])) &&
7936                        (index < JAMC_MAX_STATEMENT_LENGTH))
7937                 {
7938                     ++index;    /* skip over white space */
7939                 }
7940             }
7941             else if (statement_buffer[index] != JAMC_SEMICOLON_CHAR)
7942             {
7943                 /*
7944                  *      If no comma to seperate arguments, statement must be
7945                  *      terminated by a semicolon
7946                  */
7947                 status = JAMC_SYNTAX_ERROR;
7948             }
7949         }
7950     }
7951 
7952     if ((status == JAMC_SUCCESS) &&
7953         (statement_buffer[index] != JAMC_SEMICOLON_CHAR))
7954     {
7955         /* exceeded statement buffer length or signal count limit */
7956         status = JAMC_SYNTAX_ERROR;
7957     }
7958 
7959     if (status == JAMC_SUCCESS)
7960     {
7961         if (urj_jam_version == 2)
7962         {
7963             /* For Jam 2.0, reverse the order of the signal names */
7964             for (index = signal_count / 2; index > 0; --index)
7965             {
7966                 signal_names[signal_count] = signal_names[index - 1];
7967                 signal_names[index - 1] = signal_names[signal_count - index];
7968                 signal_names[signal_count - index] =
7969                     signal_names[signal_count];
7970             }
7971         }
7972 
7973         //if (jam_vector_map (signal_count, signal_names) == signal_count)
7974         //{
7975         //    urj_jam_vector_signal_count = signal_count;
7976         //}
7977         //else
7978         {
7979             status = JAMC_VECTOR_MAP_FAILED;
7980             urj_jam_vector_signal_count = 0;
7981         }
7982     }
7983 
7984     return status;
7985 }
7986 
7987 /****************************************************************************/
7988 /*                                                                          */
7989 
urj_jam_process_wait_cycles(char * statement_buffer,JAME_JTAG_STATE wait_state)7990 JAM_RETURN_TYPE urj_jam_process_wait_cycles
7991     (char *statement_buffer, JAME_JTAG_STATE wait_state)
7992 /*                                                                          */
7993 /*  Description:    Causes JTAG hardware to loop in the specified stable    */
7994 /*                  state for the specified number of TCK clock cycles.     */
7995 /*                                                                          */
7996 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
7997 /*                                                                          */
7998 /****************************************************************************/
7999 {
8000     int32_t cycles = 0L;
8001     JAME_EXPRESSION_TYPE expr_type = JAM_ILLEGAL_EXPR_TYPE;
8002     JAM_RETURN_TYPE status = JAMC_SUCCESS;
8003 
8004     /*
8005      *      Call parser to evaluate expression
8006      */
8007     status = urj_jam_evaluate_expression (statement_buffer, &cycles, &expr_type);
8008 
8009     /*
8010      *      Check for integer expression
8011      */
8012     if ((status == JAMC_SUCCESS) &&
8013         (expr_type != JAM_INTEGER_EXPR) &&
8014         (expr_type != JAM_INT_OR_BOOL_EXPR))
8015     {
8016         status = JAMC_TYPE_MISMATCH;
8017     }
8018 
8019     /*
8020      *      Do the JTAG hardware operation
8021      */
8022     if (status == JAMC_SUCCESS)
8023     {
8024         status = urj_jam_do_wait_cycles (cycles, wait_state);
8025     }
8026 
8027     return status;
8028 }
8029 
8030 /****************************************************************************/
8031 /*                                                                          */
8032 
urj_jam_process_wait_microseconds(char * statement_buffer,JAME_JTAG_STATE wait_state)8033 JAM_RETURN_TYPE urj_jam_process_wait_microseconds
8034     (char *statement_buffer, JAME_JTAG_STATE wait_state)
8035 /*                                                                          */
8036 /*  Description:    Causes JTAG hardware to sit in the specified stable     */
8037 /*                  state for the specified duration of real time.          */
8038 /*                                                                          */
8039 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
8040 /*                                                                          */
8041 /****************************************************************************/
8042 {
8043     int32_t microseconds = 0L;
8044     JAME_EXPRESSION_TYPE expr_type = JAM_ILLEGAL_EXPR_TYPE;
8045     JAM_RETURN_TYPE status = JAMC_SUCCESS;
8046 
8047     /*
8048      *      Call parser to evaluate expression
8049      */
8050     status = urj_jam_evaluate_expression (statement_buffer, &microseconds,
8051                                       &expr_type);
8052 
8053     /*
8054      *      Check for integer expression
8055      */
8056     if ((status == JAMC_SUCCESS) &&
8057         (expr_type != JAM_INTEGER_EXPR) &&
8058         (expr_type != JAM_INT_OR_BOOL_EXPR))
8059     {
8060         status = JAMC_TYPE_MISMATCH;
8061     }
8062 
8063     /*
8064      *      Do the JTAG hardware operation
8065      */
8066     if (status == JAMC_SUCCESS)
8067     {
8068         status = urj_jam_do_wait_microseconds (microseconds, wait_state);
8069     }
8070 
8071     return status;
8072 }
8073 
8074 /****************************************************************************/
8075 /*                                                                          */
8076 
8077 JAM_RETURN_TYPE
urj_jam_process_wait(char * statement_buffer)8078 urj_jam_process_wait (char *statement_buffer)
8079 /*                                                                          */
8080 /*  Description:    Processes WAIT statement                                */
8081 /*                                                                          */
8082 /*                  syntax: WAIT [<wait-state>,] [<integer-expr> CYCLES,]   */
8083 /*                               [<integer-expr> USEC,] [<end-state>];      */
8084 /*                                                                          */
8085 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
8086 /*                                                                          */
8087 /****************************************************************************/
8088 {
8089     int index = 0;
8090     int expr_begin = 0;
8091     int expr_end = 0;
8092     int delimiter = 0;
8093     char save_ch = 0;
8094     BOOL found_wait_state = false;
8095     BOOL found_condition = false;
8096     BOOL found_end_state = false;
8097     JAME_JTAG_STATE state = JAM_ILLEGAL_JTAG_STATE;
8098     JAME_JTAG_STATE wait_state = IDLE;
8099     JAME_JTAG_STATE end_state = IDLE;
8100     JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
8101 
8102     if ((urj_jam_version == 2) && (urj_jam_phase != JAM_PROCEDURE_PHASE))
8103     {
8104         return JAMC_PHASE_ERROR;
8105     }
8106 
8107     index = urj_jam_skip_instruction_name (statement_buffer);
8108 
8109     do
8110     {
8111         /*
8112          *      Get next argument
8113          */
8114         status = urj_jam_find_argument (&statement_buffer[index],
8115                                     &expr_begin, &expr_end, &delimiter);
8116 
8117         if (status == JAMC_SUCCESS)
8118         {
8119             expr_begin += index;
8120             expr_end += index;
8121             delimiter += index;
8122 
8123             save_ch = statement_buffer[expr_end];
8124             statement_buffer[expr_end] = JAMC_NULL_CHAR;
8125             state =
8126                 urj_jam_get_jtag_state_from_name (&statement_buffer[expr_begin]);
8127 
8128             if (state == JAM_ILLEGAL_JTAG_STATE)
8129             {
8130                 /* first argument was not a JTAG state name */
8131                 index = expr_end - 1;
8132                 while ((index > expr_begin) &&
8133                        (!isspace (statement_buffer[index])))
8134                 {
8135                     --index;
8136                 }
8137                 if ((index > expr_begin) &&
8138                     (isspace (statement_buffer[index])))
8139                 {
8140                     ++index;
8141 
8142                     if (strcmp (&statement_buffer[index], "CYCLES") == 0)
8143                     {
8144                         statement_buffer[index] = JAMC_NULL_CHAR;
8145                         status =
8146                             urj_jam_process_wait_cycles (&statement_buffer
8147                                                      [expr_begin],
8148                                                      wait_state);
8149                         statement_buffer[index] = 'C';
8150                     }
8151                     else if (strcmp (&statement_buffer[index], "USEC") ==
8152                              0)
8153                     {
8154                         statement_buffer[index] = JAMC_NULL_CHAR;
8155                         status =
8156                             urj_jam_process_wait_microseconds (&statement_buffer
8157                                                            [expr_begin],
8158                                                            wait_state);
8159                         statement_buffer[index] = 'U';
8160                     }
8161                     else
8162                     {
8163                         status = JAMC_SYNTAX_ERROR;
8164                     }
8165 
8166                     found_condition = true;
8167                 }
8168 
8169                 index = delimiter + 1;
8170             }
8171             else
8172             {
8173                 /* argument was a JTAG state name */
8174                 if ((!found_condition) && (!found_wait_state))
8175                 {
8176                     wait_state = state;
8177                     found_wait_state = true;
8178                 }
8179                 else if ((found_condition) && (!found_end_state))
8180                 {
8181                     end_state = state;
8182                     found_end_state = true;
8183                 }
8184                 else
8185                 {
8186                     status = JAMC_SYNTAX_ERROR;
8187                 }
8188 
8189                 index = delimiter + 1;
8190             }
8191 
8192             statement_buffer[expr_end] = save_ch;
8193         }
8194     }
8195     while ((status == JAMC_SUCCESS) &&
8196            (statement_buffer[delimiter] == JAMC_COMMA_CHAR));
8197 
8198     if ((status == JAMC_SUCCESS) &&
8199         (statement_buffer[delimiter] != JAMC_SEMICOLON_CHAR))
8200     {
8201         status = JAMC_SYNTAX_ERROR;
8202     }
8203 
8204     if ((status == JAMC_SUCCESS) && (!found_condition))
8205     {
8206         /* there must have been at least one condition argument */
8207         status = JAMC_SYNTAX_ERROR;
8208     }
8209 
8210     /*
8211      *      If end state was specified, go there
8212      */
8213     if ((status == JAMC_SUCCESS) && (end_state != IDLE))
8214     {
8215         status = urj_jam_goto_jtag_state (end_state);
8216     }
8217 
8218     return status;
8219 }
8220 
8221 void
urj_jam_free_literal_aca_buffers(void)8222 urj_jam_free_literal_aca_buffers (void)
8223 {
8224     int i;
8225 
8226     for (i = 0; i < JAMC_MAX_LITERAL_ARRAYS; ++i)
8227     {
8228         if (urj_jam_literal_aca_buffer[i] != NULL)
8229         {
8230             free (urj_jam_literal_aca_buffer[i]);
8231             urj_jam_literal_aca_buffer[i] = NULL;
8232         }
8233     }
8234 }
8235 
8236 /****************************************************************************/
8237 /*                                                                          */
8238 
urj_jam_execute_statement(char * statement_buffer,BOOL * done,BOOL * reuse_statement_buffer,int * exit_code)8239 JAM_RETURN_TYPE urj_jam_execute_statement
8240     (char *statement_buffer,
8241      BOOL *done, BOOL *reuse_statement_buffer, int *exit_code)
8242 /*                                                                          */
8243 /*  Description:    Processes a statement by calling the processing         */
8244 /*                  sub-function which corresponds to the instruction type  */
8245 /*                                                                          */
8246 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
8247 /*                                                                          */
8248 /****************************************************************************/
8249 {
8250     JAME_INSTRUCTION instruction_code = JAM_ILLEGAL_INSTR;
8251     JAM_RETURN_TYPE status = JAMC_SUCCESS;
8252 
8253     instruction_code = urj_jam_get_instruction (statement_buffer);
8254 
8255     switch (instruction_code)
8256     {
8257     case JAM_ACTION_INSTR:
8258         status = urj_jam_process_action (statement_buffer, done, exit_code);
8259         break;
8260 
8261     case JAM_BOOLEAN_INSTR:
8262         status = urj_jam_process_boolean (statement_buffer);
8263         break;
8264 
8265     case JAM_CALL_INSTR:
8266         status = urj_jam_process_call_or_goto (statement_buffer, true, done,
8267                                            exit_code);
8268         break;
8269 
8270     case JAM_CRC_INSTR:
8271         status = JAMC_PHASE_ERROR;
8272         break;
8273 
8274     case JAM_DATA_INSTR:
8275         status = urj_jam_process_data (statement_buffer);
8276         break;
8277 
8278     case JAM_DRSCAN_INSTR:
8279         status = urj_jam_process_drscan (statement_buffer);
8280         break;
8281 
8282     case JAM_DRSTOP_INSTR:
8283         status = urj_jam_process_drstop (statement_buffer);
8284         break;
8285 
8286     case JAM_ENDDATA_INSTR:
8287         status = urj_jam_process_return (statement_buffer, true);
8288         break;
8289 
8290     case JAM_ENDPROC_INSTR:
8291         status = urj_jam_process_return (statement_buffer, true);
8292         break;
8293 
8294     case JAM_EXIT_INSTR:
8295         status = urj_jam_process_exit (statement_buffer, done, exit_code);
8296         break;
8297 
8298     case JAM_EXPORT_INSTR:
8299         status = urj_jam_process_export (statement_buffer);
8300         break;
8301 
8302     case JAM_FOR_INSTR:
8303         status = urj_jam_process_for (statement_buffer);
8304         break;
8305 
8306     case JAM_FREQUENCY_INSTR:
8307         status = urj_jam_process_frequency (statement_buffer);
8308         break;
8309 
8310     case JAM_GOTO_INSTR:
8311         status = urj_jam_process_call_or_goto (statement_buffer, false, done,
8312                                            exit_code);
8313         break;
8314 
8315     case JAM_IF_INSTR:
8316         status = urj_jam_process_if (statement_buffer, reuse_statement_buffer);
8317         break;
8318 
8319     case JAM_INTEGER_INSTR:
8320         status = urj_jam_process_integer (statement_buffer);
8321         break;
8322 
8323     case JAM_IRSCAN_INSTR:
8324         status = urj_jam_process_irscan (statement_buffer);
8325         break;
8326 
8327     case JAM_IRSTOP_INSTR:
8328         status = urj_jam_process_irstop (statement_buffer);
8329         break;
8330 
8331     case JAM_LET_INSTR:
8332         status = urj_jam_process_assignment (statement_buffer, true);
8333         break;
8334 
8335     case JAM_NEXT_INSTR:
8336         status = urj_jam_process_next (statement_buffer);
8337         break;
8338 
8339     case JAM_NOTE_INSTR:
8340         /* ignore NOTE statements during execution */
8341         if (urj_jam_phase == JAM_UNKNOWN_PHASE)
8342         {
8343             urj_jam_phase = JAM_NOTE_PHASE;
8344         }
8345         if ((urj_jam_version == 2) && (urj_jam_phase != JAM_NOTE_PHASE))
8346         {
8347             status = JAMC_PHASE_ERROR;
8348         }
8349         break;
8350 
8351     case JAM_PADDING_INSTR:
8352         status = urj_jam_process_padding (statement_buffer);
8353         break;
8354 
8355     case JAM_POP_INSTR:
8356         status = urj_jam_process_pop (statement_buffer);
8357         break;
8358 
8359     case JAM_POSTDR_INSTR:
8360     case JAM_POSTIR_INSTR:
8361     case JAM_PREDR_INSTR:
8362     case JAM_PREIR_INSTR:
8363         status = urj_jam_process_pre_post (instruction_code, statement_buffer);
8364         break;
8365 
8366     case JAM_PRINT_INSTR:
8367         status = urj_jam_process_print (statement_buffer);
8368         break;
8369 
8370     case JAM_PROCEDURE_INSTR:
8371         status = urj_jam_process_procedure (statement_buffer);
8372         break;
8373 
8374     case JAM_PUSH_INSTR:
8375         status = urj_jam_process_push (statement_buffer);
8376         break;
8377 
8378     case JAM_REM_INSTR:
8379         /* ignore REM statements during execution */
8380         break;
8381 
8382     case JAM_RETURN_INSTR:
8383         status = urj_jam_process_return (statement_buffer, false);
8384         break;
8385 
8386     case JAM_STATE_INSTR:
8387         status = urj_jam_process_state (statement_buffer);
8388         break;
8389 
8390     case JAM_TRST_INSTR:
8391         status = urj_jam_process_trst (statement_buffer);
8392         break;
8393 
8394     case JAM_VECTOR_INSTR:
8395         status = urj_jam_process_vector (statement_buffer);
8396         break;
8397 
8398     case JAM_VMAP_INSTR:
8399         status = urj_jam_process_vmap (statement_buffer);
8400         break;
8401 
8402     case JAM_WAIT_INSTR:
8403         status = urj_jam_process_wait (statement_buffer);
8404         break;
8405 
8406     default:
8407         if ((urj_jam_version == 2) && (urj_jam_check_assignment (statement_buffer)))
8408         {
8409             status = urj_jam_process_assignment (statement_buffer, false);
8410         }
8411         else
8412         {
8413             status = JAMC_SYNTAX_ERROR;
8414         }
8415         break;
8416     }
8417 
8418     urj_jam_free_literal_aca_buffers ();
8419 
8420     return status;
8421 }
8422 
8423 /****************************************************************************/
8424 /*                                                                          */
8425 
8426 int32_t
urj_jam_get_line_of_position(int32_t position)8427 urj_jam_get_line_of_position (int32_t position)
8428 /*                                                                          */
8429 /*  Description:    Determines the line number in the input stream which    */
8430 /*                  corresponds to the given position (offset) in the       */
8431 /*                  stream.  This is used for error reporting.              */
8432 /*                                                                          */
8433 /*  Returns:        line number, or zero if it could not be determined      */
8434 /*                                                                          */
8435 /****************************************************************************/
8436 {
8437     int32_t line = 0L;
8438     int32_t index = 0L;
8439     int ch;
8440 
8441     if (urj_jam_seek (0L) == 0)
8442     {
8443         ++line;                 /* first line is line 1, not zero */
8444 
8445         for (index = 0; index < position; ++index)
8446         {
8447             ch = urj_jam_getc ();
8448 
8449             if (ch == JAMC_NEWLINE_CHAR)
8450             {
8451                 ++line;
8452             }
8453         }
8454     }
8455 
8456     return line;
8457 }
8458 
8459 /****************************************************************************/
8460 /*                                                                          */
urj_jam_execute(char * program,int32_t program_size,char * workspace,int32_t workspace_size,char * action,char ** init_list,int reset_jtag,int32_t * error_line,int * exit_code,int * format_version)8461 JAM_RETURN_TYPE urj_jam_execute
8462     (char *program,
8463      int32_t program_size,
8464      char *workspace,
8465      int32_t workspace_size,
8466      char *action,
8467      char **init_list,
8468      int reset_jtag,
8469      int32_t *error_line, int *exit_code, int *format_version)
8470 /*                                                                          */
8471 /*  Description:    This is the main entry point for executing a JAM        */
8472 /*                  program.  It returns after execution has terminated.    */
8473 /*                  The program data is not passed into this function,      */
8474 /*                  but is accessed through the urj_jam_getc() function.        */
8475 /*                                                                          */
8476 /*  Return:         JAMC_SUCCESS for successful execution, otherwise one    */
8477 /*                  of the error codes listed in <jamexprt.h>               */
8478 /*                                                                          */
8479 /****************************************************************************/
8480 {
8481     JAM_RETURN_TYPE status = JAMC_SUCCESS;
8482     char *statement_buffer = NULL;
8483     char label_buffer[JAMC_MAX_NAME_LENGTH + 1];
8484     BOOL done = false;
8485     BOOL reuse_statement_buffer = false;
8486     int i = 0;
8487 
8488     urj_jam_program = program;
8489     urj_jam_program_size = program_size;
8490     urj_jam_workspace = workspace;
8491     urj_jam_workspace_size = workspace_size;
8492     urj_jam_action = action;
8493     urj_jam_init_list = init_list;
8494 
8495     urj_jam_current_file_position = 0L;
8496     urj_jam_current_statement_position = 0L;
8497     urj_jam_next_statement_position = 0L;
8498     urj_jam_vector_signal_count = 0;
8499     urj_jam_version = 0;
8500     urj_jam_phase = JAM_UNKNOWN_PHASE;
8501     urj_jam_current_block = NULL;
8502 
8503     for (i = 0; i < JAMC_MAX_LITERAL_ARRAYS; ++i)
8504     {
8505         urj_jam_literal_aca_buffer[i] = NULL;
8506     }
8507 
8508     /*
8509      *      Ensure that workspace is DWORD aligned
8510      */
8511     if (urj_jam_workspace != NULL)
8512     {
8513         urj_jam_workspace_size -= (((int32_t) urj_jam_workspace) & 3L);
8514         urj_jam_workspace_size &= (~3L);
8515         urj_jam_workspace = (char *) (((int32_t) urj_jam_workspace + 3L) & (~3L));
8516     }
8517 
8518     /*
8519      *      Initialize symbol table and stack
8520      */
8521     status = urj_jam_init_symbol_table ();
8522 
8523     if (status == JAMC_SUCCESS)
8524     {
8525         status = urj_jam_init_stack ();
8526     }
8527 
8528     if (status == JAMC_SUCCESS)
8529     {
8530         status = urj_jam_init_jtag ();
8531     }
8532 
8533     if (status == JAMC_SUCCESS)
8534     {
8535         status = urj_jam_init_heap ();
8536     }
8537 
8538     if (status == JAMC_SUCCESS)
8539     {
8540         status = urj_jam_seek (0L);
8541     }
8542 
8543     if (status == JAMC_SUCCESS)
8544     {
8545         statement_buffer = malloc (JAMC_MAX_STATEMENT_LENGTH + 1024);
8546 
8547         if (statement_buffer == NULL)
8548         {
8549             status = JAMC_OUT_OF_MEMORY;
8550         }
8551     }
8552 
8553     /*
8554      *      Get program statements and execute them
8555      */
8556     while ((!done) && (status == JAMC_SUCCESS))
8557     {
8558         if (!reuse_statement_buffer)
8559         {
8560             status = urj_jam_get_statement (statement_buffer, label_buffer);
8561 
8562             if ((status == JAMC_SUCCESS)
8563                 && (label_buffer[0] != JAMC_NULL_CHAR))
8564             {
8565                 status = urj_jam_add_symbol
8566                     (JAM_LABEL,
8567                      label_buffer, 0L, urj_jam_current_statement_position);
8568             }
8569         }
8570         else
8571         {
8572             /* statement buffer will be reused -- clear the flag */
8573             reuse_statement_buffer = false;
8574         }
8575 
8576         if (status == JAMC_SUCCESS)
8577         {
8578             status = urj_jam_execute_statement
8579                 (statement_buffer, &done, &reuse_statement_buffer, exit_code);
8580         }
8581     }
8582 
8583     if ((status != JAMC_SUCCESS) && (error_line != NULL))
8584     {
8585         *error_line =
8586             urj_jam_get_line_of_position (urj_jam_current_statement_position);
8587     }
8588 
8589     urj_jam_free_literal_aca_buffers ();
8590     urj_jam_free_jtag_padding_buffers (reset_jtag);
8591     urj_jam_free_heap ();
8592     urj_jam_free_stack ();
8593     urj_jam_free_symbol_table ();
8594 
8595     if (statement_buffer != NULL)
8596         free (statement_buffer);
8597 
8598     if (format_version != NULL)
8599         *format_version = urj_jam_version;
8600 
8601     return status;
8602 }
8603