source: trunk/minix/commands/bc/storage.c@ 9

Last change on this file since 9 was 9, checked in by Mattia Monga, 13 years ago

Minix 3.1.2a

File size: 19.9 KB
RevLine 
[9]1/* storage.c: Code and data storage manipulations. This includes labels. */
2
3/* This file is part of bc written for MINIX.
4 Copyright (C) 1991, 1992 Free Software Foundation, Inc.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License , or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
19
20 You may contact the author by:
21 e-mail: phil@cs.wwu.edu
22 us-mail: Philip A. Nelson
23 Computer Science Department, 9062
24 Western Washington University
25 Bellingham, WA 98226-9062
26
27*************************************************************************/
28
29#include "bcdefs.h"
30#include "global.h"
31#include "proto.h"
32
33
34/* Initialize the storage at the beginning of the run. */
35
36void
37init_storage ()
38{
39
40 /* Functions: we start with none and ask for more. */
41 f_count = 0;
42 more_functions ();
43 f_names[0] = "(main)";
44
45 /* Variables. */
46 v_count = 0;
47 more_variables ();
48
49 /* Arrays. */
50 a_count = 0;
51 more_arrays ();
52
53 /* Other things... */
54 ex_stack = NULL;
55 fn_stack = NULL;
56 i_base = 10;
57 o_base = 10;
58 scale = 0;
59 c_code = FALSE;
60 init_numbers();
61}
62
63/* Three functions for increasing the number of functions, variables, or
64 arrays that are needed. This adds another 32 of the requested object. */
65
66void
67more_functions (VOID)
68{
69 int old_count;
70 int indx1, indx2;
71 bc_function *old_f;
72 bc_function *f;
73 char **old_names;
74
75 /* Save old information. */
76 old_count = f_count;
77 old_f = functions;
78 old_names = f_names;
79
80 /* Add a fixed amount and allocate new space. */
81 f_count += STORE_INCR;
82 functions = (bc_function *) bc_malloc (f_count*sizeof (bc_function));
83 f_names = (char **) bc_malloc (f_count*sizeof (char *));
84
85 /* Copy old ones. */
86 for (indx1 = 0; indx1 < old_count; indx1++)
87 {
88 functions[indx1] = old_f[indx1];
89 f_names[indx1] = old_names[indx1];
90 }
91
92 /* Initialize the new ones. */
93 for (; indx1 < f_count; indx1++)
94 {
95 f = &functions[indx1];
96 f->f_defined = FALSE;
97 for (indx2 = 0; indx2 < BC_MAX_SEGS; indx2++)
98 f->f_body [indx2] = NULL;
99 f->f_code_size = 0;
100 f->f_label = NULL;
101 f->f_autos = NULL;
102 f->f_params = NULL;
103 }
104
105 /* Free the old elements. */
106 if (old_count != 0)
107 {
108 free (old_f);
109 free (old_names);
110 }
111}
112
113void
114more_variables ()
115{
116 int indx;
117 int old_count;
118 bc_var **old_var;
119 char **old_names;
120
121 /* Save the old values. */
122 old_count = v_count;
123 old_var = variables;
124 old_names = v_names;
125
126 /* Increment by a fixed amount and allocate. */
127 v_count += STORE_INCR;
128 variables = (bc_var **) bc_malloc (v_count*sizeof(bc_var *));
129 v_names = (char **) bc_malloc (v_count*sizeof(char *));
130
131 /* Copy the old variables. */
132 for (indx = 3; indx < old_count; indx++)
133 variables[indx] = old_var[indx];
134
135 /* Initialize the new elements. */
136 for (; indx < v_count; indx++)
137 variables[indx] = NULL;
138
139 /* Free the old elements. */
140 if (old_count != 0)
141 {
142 free (old_var);
143 free (old_names);
144 }
145}
146
147void
148more_arrays ()
149{
150 int indx;
151 int old_count;
152 bc_var_array **old_ary;
153 char **old_names;
154
155 /* Save the old values. */
156 old_count = a_count;
157 old_ary = arrays;
158 old_names = a_names;
159
160 /* Increment by a fixed amount and allocate. */
161 a_count += STORE_INCR;
162 arrays = (bc_var_array **) bc_malloc (a_count*sizeof(bc_var_array *));
163 a_names = (char **) bc_malloc (a_count*sizeof(char *));
164
165 /* Copy the old arrays. */
166 for (indx = 1; indx < old_count; indx++)
167 arrays[indx] = old_ary[indx];
168
169
170 /* Initialize the new elements. */
171 for (; indx < v_count; indx++)
172 arrays[indx] = NULL;
173
174 /* Free the old elements. */
175 if (old_count != 0)
176 {
177 free (old_ary);
178 free (old_names);
179 }
180}
181
182
183/* clear_func clears out function FUNC and makes it ready to redefine. */
184
185void
186clear_func (func)
187 char func;
188{
189 bc_function *f;
190 int indx;
191 bc_label_group *lg;
192
193 /* Set the pointer to the function. */
194 f = &functions[func];
195 f->f_defined = FALSE;
196
197 /* Clear the code segments. */
198 for (indx = 0; indx < BC_MAX_SEGS; indx++)
199 {
200 if (f->f_body[indx] != NULL)
201 {
202 free (f->f_body[indx]);
203 f->f_body[indx] = NULL;
204 }
205 }
206
207 f->f_code_size = 0;
208 if (f->f_autos != NULL)
209 {
210 free_args (f->f_autos);
211 f->f_autos = NULL;
212 }
213 if (f->f_params != NULL)
214 {
215 free_args (f->f_params);
216 f->f_params = NULL;
217 }
218 while (f->f_label != NULL)
219 {
220 lg = f->f_label->l_next;
221 free (f->f_label);
222 f->f_label = lg;
223 }
224}
225
226
227/* Pop the function execution stack and return the top. */
228
229int
230fpop()
231{
232 fstack_rec *temp;
233 int retval;
234
235 if (fn_stack != NULL)
236 {
237 temp = fn_stack;
238 fn_stack = temp->s_next;
239 retval = temp->s_val;
240 free (temp);
241 }
242 return (retval);
243}
244
245
246/* Push VAL on to the function stack. */
247
248void
249fpush (val)
250 int val;
251{
252 fstack_rec *temp;
253
254 temp = (fstack_rec *) bc_malloc (sizeof (fstack_rec));
255 temp->s_next = fn_stack;
256 temp->s_val = val;
257 fn_stack = temp;
258}
259
260
261/* Pop and discard the top element of the regular execution stack. */
262
263void
264pop ()
265{
266 estack_rec *temp;
267
268 if (ex_stack != NULL)
269 {
270 temp = ex_stack;
271 ex_stack = temp->s_next;
272 free_num (&temp->s_num);
273 free (temp);
274 }
275}
276
277
278/* Push a copy of NUM on to the regular execution stack. */
279
280void
281push_copy (num)
282 bc_num num;
283{
284 estack_rec *temp;
285
286 temp = (estack_rec *) bc_malloc (sizeof (estack_rec));
287 temp->s_num = copy_num (num);
288 temp->s_next = ex_stack;
289 ex_stack = temp;
290}
291
292
293/* Push NUM on to the regular execution stack. Do NOT push a copy. */
294
295void
296push_num (num)
297 bc_num num;
298{
299 estack_rec *temp;
300
301 temp = (estack_rec *) bc_malloc (sizeof (estack_rec));
302 temp->s_num = num;
303 temp->s_next = ex_stack;
304 ex_stack = temp;
305}
306
307
308/* Make sure the ex_stack has at least DEPTH elements on it.
309 Return TRUE if it has at least DEPTH elements, otherwise
310 return FALSE. */
311
312char
313check_stack (depth)
314 int depth;
315{
316 estack_rec *temp;
317
318 temp = ex_stack;
319 while ((temp != NULL) && (depth > 0))
320 {
321 temp = temp->s_next;
322 depth--;
323 }
324 if (depth > 0)
325 {
326 rt_error ("Stack error.");
327 return FALSE;
328 }
329 return TRUE;
330}
331
332
333/* The following routines manipulate simple variables and
334 array variables. */
335
336/* get_var returns a pointer to the variable VAR_NAME. If one does not
337 exist, one is created. */
338
339bc_var *
340get_var (var_name)
341 int var_name;
342{
343 bc_var *var_ptr;
344
345 var_ptr = variables[var_name];
346 if (var_ptr == NULL)
347 {
348 var_ptr = variables[var_name] = (bc_var *) bc_malloc (sizeof (bc_var));
349 init_num (&var_ptr->v_value);
350 }
351 return var_ptr;
352}
353
354
355/* get_array_num returns the address of the bc_num in the array
356 structure. If more structure is requried to get to the index,
357 this routine does the work to create that structure. VAR_INDEX
358 is a zero based index into the arrays storage array. INDEX is
359 the index into the bc array. */
360
361bc_num *
362get_array_num (var_index, index)
363 int var_index;
364 long index;
365{
366 bc_var_array *ary_ptr;
367 bc_array *a_var;
368 bc_array_node *temp;
369 int log, ix, ix1;
370 int sub [NODE_DEPTH];
371
372 /* Get the array entry. */
373 ary_ptr = arrays[var_index];
374 if (ary_ptr == NULL)
375 {
376 ary_ptr = arrays[var_index] =
377 (bc_var_array *) bc_malloc (sizeof (bc_var_array));
378 ary_ptr->a_value = NULL;
379 ary_ptr->a_next = NULL;
380 ary_ptr->a_param = FALSE;
381 }
382
383 a_var = ary_ptr->a_value;
384 if (a_var == NULL) {
385 a_var = ary_ptr->a_value = (bc_array *) bc_malloc (sizeof (bc_array));
386 a_var->a_tree = NULL;
387 a_var->a_depth = 0;
388 }
389
390 /* Get the index variable. */
391 sub[0] = index & NODE_MASK;
392 ix = index >> NODE_SHIFT;
393 log = 1;
394 while (ix > 0 || log < a_var->a_depth)
395 {
396 sub[log] = ix & NODE_MASK;
397 ix >>= NODE_SHIFT;
398 log++;
399 }
400
401 /* Build any tree that is necessary. */
402 while (log > a_var->a_depth)
403 {
404 temp = (bc_array_node *) bc_malloc (sizeof(bc_array_node));
405 if (a_var->a_depth != 0)
406 {
407 temp->n_items.n_down[0] = a_var->a_tree;
408 for (ix=1; ix < NODE_SIZE; ix++)
409 temp->n_items.n_down[ix] = NULL;
410 }
411 else
412 {
413 for (ix=0; ix < NODE_SIZE; ix++)
414 temp->n_items.n_num[ix] = copy_num(_zero_);
415 }
416 a_var->a_tree = temp;
417 a_var->a_depth++;
418 }
419
420 /* Find the indexed variable. */
421 temp = a_var->a_tree;
422 while ( log-- > 1)
423 {
424 ix1 = sub[log];
425 if (temp->n_items.n_down[ix1] == NULL)
426 {
427 temp->n_items.n_down[ix1] =
428 (bc_array_node *) bc_malloc (sizeof(bc_array_node));
429 temp = temp->n_items.n_down[ix1];
430 if (log > 1)
431 for (ix=0; ix < NODE_SIZE; ix++)
432 temp->n_items.n_down[ix] = NULL;
433 else
434 for (ix=0; ix < NODE_SIZE; ix++)
435 temp->n_items.n_num[ix] = copy_num(_zero_);
436 }
437 else
438 temp = temp->n_items.n_down[ix1];
439 }
440
441 /* Return the address of the indexed variable. */
442 return &(temp->n_items.n_num[sub[0]]);
443}
444
445
446/* Store the top of the execution stack into VAR_NAME.
447 This includes the special variables ibase, obase, and scale. */
448
449void
450store_var (var_name)
451 int var_name;
452{
453 bc_var *var_ptr;
454 long temp;
455 char toobig;
456
457 if (var_name > 2)
458 {
459 /* It is a simple variable. */
460 var_ptr = get_var (var_name);
461 if (var_ptr != NULL)
462 {
463 free_num(&var_ptr->v_value);
464 var_ptr->v_value = copy_num (ex_stack->s_num);
465 }
466 }
467 else
468 {
469 /* It is a special variable... */
470 toobig = FALSE;
471 if (is_neg (ex_stack->s_num))
472 {
473 switch (var_name)
474 {
475 case 0:
476 rt_warn ("negative ibase, set to 2");
477 temp = 2;
478 break;
479 case 1:
480 rt_warn ("negative obase, set to 2");
481 temp = 2;
482 break;
483 case 2:
484 rt_warn ("negative scale, set to 0");
485 temp = 0;
486 break;
487 }
488 }
489 else
490 {
491 temp = num2long (ex_stack->s_num);
492 if (!is_zero (ex_stack->s_num) && temp == 0)
493 toobig = TRUE;
494 }
495 switch (var_name)
496 {
497 case 0:
498 if (temp < 2 && !toobig)
499 {
500 i_base = 2;
501 rt_warn ("ibase too small, set to 2");
502 }
503 else
504 if (temp > 16 || toobig)
505 {
506 i_base = 16;
507 rt_warn ("ibase too large, set to 16");
508 }
509 else
510 i_base = (int) temp;
511 break;
512
513 case 1:
514 if (temp < 2 && !toobig)
515 {
516 o_base = 2;
517 rt_warn ("obase too small, set to 2");
518 }
519 else
520 if (temp > BC_BASE_MAX || toobig)
521 {
522 o_base = BC_BASE_MAX;
523 rt_warn ("obase too large, set to %d", BC_BASE_MAX);
524 }
525 else
526 o_base = (int) temp;
527 break;
528
529 case 2:
530 /* WARNING: The following if statement may generate a compiler
531 warning if INT_MAX == LONG_MAX. This is NOT a problem. */
532 if (temp > BC_SCALE_MAX || toobig )
533 {
534 scale = BC_SCALE_MAX;
535 rt_warn ("scale too large, set to %d", BC_SCALE_MAX);
536 }
537 else
538 scale = (int) temp;
539 }
540 }
541}
542
543
544/* Store the top of the execution stack into array VAR_NAME.
545 VAR_NAME is the name of an array, and the next to the top
546 of stack for the index into the array. */
547
548void
549store_array (var_name)
550 int var_name;
551{
552 bc_num *num_ptr;
553 long index;
554
555 if (!check_stack(2)) return;
556 index = num2long (ex_stack->s_next->s_num);
557 if (index < 0 || index > BC_DIM_MAX ||
558 (index == 0 && !is_zero(ex_stack->s_next->s_num)))
559 rt_error ("Array %s subscript out of bounds.", a_names[var_name]);
560 else
561 {
562 num_ptr = get_array_num (var_name, index);
563 if (num_ptr != NULL)
564 {
565 free_num (num_ptr);
566 *num_ptr = copy_num (ex_stack->s_num);
567 free_num (&ex_stack->s_next->s_num);
568 ex_stack->s_next->s_num = ex_stack->s_num;
569 init_num (&ex_stack->s_num);
570 pop();
571 }
572 }
573}
574
575
576/* Load a copy of VAR_NAME on to the execution stack. This includes
577 the special variables ibase, obase and scale. */
578
579void
580load_var (var_name)
581 int var_name;
582{
583 bc_var *var_ptr;
584
585 switch (var_name)
586 {
587
588 case 0:
589 /* Special variable ibase. */
590 push_copy (_zero_);
591 int2num (&ex_stack->s_num, i_base);
592 break;
593
594 case 1:
595 /* Special variable obase. */
596 push_copy (_zero_);
597 int2num (&ex_stack->s_num, o_base);
598 break;
599
600 case 2:
601 /* Special variable scale. */
602 push_copy (_zero_);
603 int2num (&ex_stack->s_num, scale);
604 break;
605
606 default:
607 /* It is a simple variable. */
608 var_ptr = variables[var_name];
609 if (var_ptr != NULL)
610 push_copy (var_ptr->v_value);
611 else
612 push_copy (_zero_);
613 }
614}
615
616
617/* Load a copy of VAR_NAME on to the execution stack. This includes
618 the special variables ibase, obase and scale. */
619
620void
621load_array (var_name)
622 int var_name;
623{
624 bc_num *num_ptr;
625 long index;
626
627 if (!check_stack(1)) return;
628 index = num2long (ex_stack->s_num);
629 if (index < 0 || index > BC_DIM_MAX ||
630 (index == 0 && !is_zero(ex_stack->s_num)))
631 rt_error ("Array %s subscript out of bounds.", a_names[var_name]);
632 else
633 {
634 num_ptr = get_array_num (var_name, index);
635 if (num_ptr != NULL)
636 {
637 pop();
638 push_copy (*num_ptr);
639 }
640 }
641}
642
643
644/* Decrement VAR_NAME by one. This includes the special variables
645 ibase, obase, and scale. */
646
647void
648decr_var (var_name)
649 int var_name;
650{
651 bc_var *var_ptr;
652
653 switch (var_name)
654 {
655
656 case 0: /* ibase */
657 if (i_base > 2)
658 i_base--;
659 else
660 rt_warn ("ibase too small in --");
661 break;
662
663 case 1: /* obase */
664 if (o_base > 2)
665 o_base--;
666 else
667 rt_warn ("obase too small in --");
668 break;
669
670 case 2: /* scale */
671 if (scale > 0)
672 scale--;
673 else
674 rt_warn ("scale can not be negative in -- ");
675 break;
676
677 default: /* It is a simple variable. */
678 var_ptr = get_var (var_name);
679 if (var_ptr != NULL)
680 bc_sub (var_ptr->v_value,_one_,&var_ptr->v_value);
681 }
682}
683
684
685/* Decrement VAR_NAME by one. VAR_NAME is an array, and the top of
686 the execution stack is the index and it is popped off the stack. */
687
688void
689decr_array (var_name)
690 char var_name;
691{
692 bc_num *num_ptr;
693 long index;
694
695 /* It is an array variable. */
696 if (!check_stack (1)) return;
697 index = num2long (ex_stack->s_num);
698 if (index < 0 || index > BC_DIM_MAX ||
699 (index == 0 && !is_zero (ex_stack->s_num)))
700 rt_error ("Array %s subscript out of bounds.", a_names[var_name]);
701 else
702 {
703 num_ptr = get_array_num (var_name, index);
704 if (num_ptr != NULL)
705 {
706 pop ();
707 bc_sub (*num_ptr, _one_, num_ptr);
708 }
709 }
710}
711
712
713/* Increment VAR_NAME by one. This includes the special variables
714 ibase, obase, and scale. */
715
716void
717incr_var (var_name)
718 int var_name;
719{
720 bc_var *var_ptr;
721
722 switch (var_name)
723 {
724
725 case 0: /* ibase */
726 if (i_base < 16)
727 i_base++;
728 else
729 rt_warn ("ibase too big in ++");
730 break;
731
732 case 1: /* obase */
733 if (o_base < BC_BASE_MAX)
734 o_base++;
735 else
736 rt_warn ("obase too big in ++");
737 break;
738
739 case 2:
740 if (scale < BC_SCALE_MAX)
741 scale++;
742 else
743 rt_warn ("Scale too big in ++");
744 break;
745
746 default: /* It is a simple variable. */
747 var_ptr = get_var (var_name);
748 if (var_ptr != NULL)
749 bc_add (var_ptr->v_value, _one_, &var_ptr->v_value);
750
751 }
752}
753
754
755/* Increment VAR_NAME by one. VAR_NAME is an array and top of
756 execution stack is the index and is popped off the stack. */
757
758void
759incr_array (var_name)
760 int var_name;
761{
762 bc_num *num_ptr;
763 long index;
764
765 if (!check_stack (1)) return;
766 index = num2long (ex_stack->s_num);
767 if (index < 0 || index > BC_DIM_MAX ||
768 (index == 0 && !is_zero (ex_stack->s_num)))
769 rt_error ("Array %s subscript out of bounds.", a_names[var_name]);
770 else
771 {
772 num_ptr = get_array_num (var_name, index);
773 if (num_ptr != NULL)
774 {
775 pop ();
776 bc_add (*num_ptr, _one_, num_ptr);
777 }
778 }
779}
780
781
782/* Routines for processing autos variables and parameters. */
783
784/* NAME is an auto variable that needs to be pushed on its stack. */
785
786void
787auto_var (name)
788 int name;
789{
790 bc_var *v_temp;
791 bc_var_array *a_temp;
792 int ix;
793
794 if (name > 0)
795 {
796 /* A simple variable. */
797 ix = name;
798 v_temp = (bc_var *) bc_malloc (sizeof (bc_var));
799 v_temp->v_next = variables[ix];
800 init_num (&v_temp->v_value);
801 variables[ix] = v_temp;
802 }
803 else
804 {
805 /* An array variable. */
806 ix = -name;
807 a_temp = (bc_var_array *) bc_malloc (sizeof (bc_var_array));
808 a_temp->a_next = arrays[ix];
809 a_temp->a_value = NULL;
810 a_temp->a_param = FALSE;
811 arrays[ix] = a_temp;
812 }
813}
814
815
816/* Free_a_tree frees everything associated with an array variable tree.
817 This is used when popping an array variable off its auto stack. */
818
819void
820free_a_tree ( root, depth )
821 bc_array_node *root;
822 int depth;
823{
824 int ix;
825
826 if (root != NULL)
827 {
828 if (depth > 1)
829 for (ix = 0; ix < NODE_SIZE; ix++)
830 free_a_tree (root->n_items.n_down[ix], depth-1);
831 else
832 for (ix = 0; ix < NODE_SIZE; ix++)
833 free_num ( &(root->n_items.n_num[ix]));
834 free (root);
835 }
836}
837
838
839/* LIST is an NULL terminated list of varible names that need to be
840 popped off their auto stacks. */
841
842void
843pop_vars (list)
844 arg_list *list;
845{
846 bc_var *v_temp;
847 bc_var_array *a_temp;
848 int ix;
849
850 while (list != NULL)
851 {
852 ix = list->av_name;
853 if (ix > 0)
854 {
855 /* A simple variable. */
856 v_temp = variables[ix];
857 if (v_temp != NULL)
858 {
859 variables[ix] = v_temp->v_next;
860 free_num (&v_temp->v_value);
861 free (v_temp);
862 }
863 }
864 else
865 {
866 /* An array variable. */
867 ix = -ix;
868 a_temp = arrays[ix];
869 if (a_temp != NULL)
870 {
871 arrays[ix] = a_temp->a_next;
872 if (!a_temp->a_param && a_temp->a_value != NULL)
873 {
874 free_a_tree (a_temp->a_value->a_tree,
875 a_temp->a_value->a_depth);
876 free (a_temp->a_value);
877 }
878 free (a_temp);
879 }
880 }
881 list = list->next;
882 }
883}
884
885
886/* A call is being made to FUNC. The call types are at PC. Process
887 the parameters by doing an auto on the parameter variable and then
888 store the value at the new variable or put a pointer the the array
889 variable. */
890
891void
892process_params (pc, func)
893 program_counter *pc;
894 int func;
895{
896 char ch;
897 arg_list *params;
898 char warned = FALSE;
899 int ix, ix1;
900 bc_var *v_temp;
901 bc_var_array *a_src, *a_dest;
902 bc_num *n_temp;
903
904 /* Get the parameter names from the function. */
905 params = functions[func].f_params;
906
907 while ((ch = byte(pc)) != ':')
908 {
909 if (params != NULL)
910 {
911 if ((ch == '0') && params->av_name > 0)
912 {
913 /* A simple variable. */
914 ix = params->av_name;
915 v_temp = (bc_var *) bc_malloc (sizeof(bc_var));
916 v_temp->v_next = variables[ix];
917 v_temp->v_value = ex_stack->s_num;
918 init_num (&ex_stack->s_num);
919 variables[ix] = v_temp;
920 }
921 else
922 if ((ch == '1') && (params->av_name < 0))
923 {
924 /* The variables is an array variable. */
925
926 /* Compute source index and make sure some structure exists. */
927 ix = (int) num2long (ex_stack->s_num);
928 n_temp = get_array_num (ix, 0);
929
930 /* Push a new array and Compute Destination index */
931 auto_var (params->av_name);
932 ix1 = -params->av_name;
933
934 /* Set up the correct pointers in the structure. */
935 if (ix == ix1)
936 a_src = arrays[ix]->a_next;
937 else
938 a_src = arrays[ix];
939 a_dest = arrays[ix1];
940 a_dest->a_param = TRUE;
941 a_dest->a_value = a_src->a_value;
942 }
943 else
944 {
945 if (params->av_name < 0)
946 rt_error ("Parameter type mismatch parameter %s.",
947 a_names[-params->av_name]);
948 else
949 rt_error ("Parameter type mismatch, parameter %s.",
950 v_names[params->av_name]);
951 params++;
952 }
953 pop ();
954 }
955 else
956 {
957 if (!warned)
958 {
959 rt_error ("Parameter number mismatch");
960 warned = TRUE;
961 }
962 }
963 params = params->next;
964 }
965 if (params != NULL)
966 rt_error ("Parameter number mismatch");
967}
Note: See TracBrowser for help on using the repository browser.