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, µseconds,
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