1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 call:
24 proc;
25 cl: entry;
26
27
28
29
30 display_usage:
31 proc;
32
33 call ioa_ ("^(^a^)",
34 "Syntax as a command:
35 call {global_opts} virtual_entry {arg_value_specifiers}
36
37 Syntax as an active function:
38 [call {global_opts} virtual_entry {arg_value_specifiers}]",
39 "
40
41 Arguments:
42 virtual_entry
43 character representation of an external entrypoint to be invoked.
44 Format of this string is described in: virtual_entries.gi.info",
45 "
46 arg_value_specifier
47 one or more strings and options defining an argument to be passed to
48 the entrypoint. See ""List of arg_value_specifiers"".",
49 "
50
51
52 List of arg_value specifiers:
53 -input arg_value {arg_options},
54 -in arg_value {arg_options},
55 -i arg_value {arg_options},
56 arg_value {arg_options}",
57 "
58 gives an initial value for an entrypoint input argument before the
59 call is made. -input is the default if no direction option is
60 given with an arg_value.",
61 "
62 -inout arg_value {arg_options},
63 -io arg_value {arg_options}
64 sets the initial value of an entrypoint input-output argument
65 before the call is made. The argument value is displayed after
66 the entrypoint returns.",
67 "
68
69 -output {arg_options},
70 -out {arg_options},
71 -o {arg_options}
72 no arg_value is provided; entrypoint argument value is displayed
73 after the entrypoint returns. ",
74 "
75 -outignore {arg_options},
76 -ignore {arg_options},
77 -ig {arg_options}
78 argument value is not displayed after the entrypoint returns.",
79 "
80
81
82 List of arg_options:
83 -id ID
84 gives a PL/I identifier naming the argument.
85 -return, -ret
86 return this argument when call is invoked as an active function.",
87 "
88 -octal, -oc
89 displays an octal representation of storage for the argument,
90 as well as the character string interpretation.",
91 "
92
93 -code, -cd
94 argument is a Multics status code. For an input argument,
95 arg_value is a string naming a status code value.",
96 "
97 -date_time,
98 -date, -dt,
99 -time, -tm
100 argument is a Multics clock value (fixed bin(71) aligned). For an
101 input argument, arg_value is a string representation of a date or
102 time value. For an output argument, clock value is converted to",
103 "
104 default process date_time, date, or time format.",
105 "
106
107 -declare DECLARATION,
108 -dcl DECLARATION
109 argument has the attributes given in DECLARATION. A descriptor
110 with these attributes is passed with this argument.",
111 "
112 -addr DECLARATION
113 for a pointer argument, set its value to point to storage
114 described by the PL/I DECLARATION, which is a single string
115 defining data type and length attributes (e.g., ""char(20)"").",
116 "
117 For an input argument, the arg_value initializes this storage.
118 For an output argument, the addressed storage is displayed.",
119 "
120
121 -max_length M, -ml M
122 for a string or area parameter with star extents (e.g., char(*),
123 char(*) var, bit(*), bit(*) var, area(*)), M is the length in
124 characters, bits or area words of the corresponding argument.",
125 "
126 -length L, -ln L
127 -length ID, -ln ID
128 for a string argument, L gives the length in characters or bits to
129 be displayed upon return from the entrypoint. The ID format gives
130 the identifier of another argument whose output value specifies",
131 "
132 the display length.",
133 "
134
135
136 List of global options:
137 -all, -a
138 Display all arguments upon return from virtual_entry.
139 -octal, -oc
140 Display all arguments with an octal representation of their
141 storage.",
142 "
143 -debug INT, -db INT
144 Display debug information as calling the virtual_entry proceeds.
145 An INT equaling 1 provides basic debugging data; 2, 3, 4, or 5
146 provides more details.",
147 "
148
149
150 Example:
151 initiate_file_ has the following PL/I calling sequence:
152
153 call initiate_file_( dir, entry, access_mode, ptr, bit_count, code);
154
155 The display_entry_point_dcl (depd) command displays the parameter types:
156
157 depd initiate_file_",
158 "
159 dcl initiate_file_ entry(char(*), char(*), bit(*), ptr,
160 fixed bin(24), fixed bin(35));
161
162 Invoke initiate_file_, specifying an initial value for each parameter:
163
164 call initiate_file_ [wd] my_file 100 -o -o -o -cd");
165 call ioa_ ("^/^4-version:^-^a", CALL_VERSION);
166
167 end display_usage;
168 %page;
169
170
171
172
173
174
175
176
177 %include std_descriptor_types;
178 %page;
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252 %page;
253
254
255
256
257
258 dcl CALL_VERSION char(20) varying int static options(constant) init("call.01.04");
259 dcl (F init("0"b), T init("1"b)) bit(1) aligned int static options(constant);
260
261 dcl MaxLineLen fixed bin int static options(constant) init(80);
262 dcl NEG_SIGN_BITS bit(72) aligned int static options(constant) init((72)"1"b);
263 dcl NL char(1) int static options(constant) init("
264 ");
265 dcl NULL_POINTER char(4) int static options(constant) init("-1|1");
266 dcl PROC char (4) int static options (constant) init ("call");
267 dcl ZEROb bit(1) int static options(constant) init("0"b);
268
269 dcl (call_et_$array_unsupported,
270 call_et_$bad_declaration,
271 call_et_$dtype_unsupported,
272 call_et_$no_entrypoint_info,
273 call_et_$overflow_error,
274 call_et_$parameter_type_unsupported,
275 call_et_$star_extent_unresolved,
276 call_et_$structure_unsupported,
277 call_et_$underflow_error,
278 error_table_$bad_arg,
279 error_table_$bad_conversion,
280 error_table_$bad_index,
281 error_table_$badopt,
282 error_table_$bigarg,
283 error_table_$fatal_error,
284 error_table_$inconsistent,
285 error_table_$noarg,
286 error_table_$no_r_permission,
287 error_table_$not_act_fnc,
288 error_table_$oldnamerr,
289 error_table_$size_error,
290 error_table_$smallarg,
291 error_table_$too_many_args) fixed bin (35) ext static;
292
293 dcl assign_ entry (ptr, fixed bin, fixed bin(35), ptr, fixed bin, fixed bin(35));
294 dcl ioa_ entry () options (variable);
295 dcl ioa_$nnl entry () options (variable);
296 dcl ioa_$rsnnl entry() options(variable);
297
298 dcl (addr, addrel, after, before, binary, char, codeptr, copy, divide, environmentptr,
299 hbound, index, lbound, length, ltrim, maxlength, min, mod, null,
300 reverse, rtrim, size, substr, unspec) builtin;
301
302 dcl cleanup condition;
303 %page;
304
305
306
307
308
309
310 entry_info_ptr = null;
311
312
313
314 dcl command bit (1) aligned;
315
316 dcl af_retL fixed bin (21);
317 dcl af_retP ptr;
318 dcl af_ret char (af_retL) varying based(af_retP);
319
320 dcl gripe entry variable options(variable);
321 dcl code fixed bin (35);
322
323 dcl cu_$arg_list_ptr entry() returns (ptr);
324
325 call argSetup( cu_$arg_list_ptr(), command, af_retP, af_retL, gripe);
326
327 if ^argsRemain() then do;
328 call display_usage();
329 go to EXIT_call;
330 end;
331
332
333
334
335
336
337
338
339
340 dcl 1 globalOpt aligned,
341 2 debug fixed bin(3) unsigned init(0), debugdebug
342
343 2 xtra fixed bin(2);
344
345
346 dcl 1 veArg aligned like source;
347
348 dcl virtualEntry char (veArg.argL) based (veArg.argP);
349
350
351 unspec(veArg) = ZEROb;
352 veArg.argP = null();
353 veArg.M, veArg.L, veArg.L_idX = Lunset;
354 veArg.id = "virtual_entry";
355
356 call argValue (0, veArg, globalOpt, code);
357 if code ^= 0 then do;
358 call gripe (code, PROC, "Failed to get virtual_entry to be called.");
359 return;
360 end;
361
362 globalOpt.xtra = veArg.xtra;
363 %page;
364
365
366
367
368
369
370
371
372
373
374 if globalOpt.debug >= 5 then
375 call ioa_ ("Task 3 begins...");
376
377 dcl 1 ei aligned like entry_info_header based(entry_info_ptr);
378
379
380 dcl entry_description char(2000) varying;
381
382
383 dcl entry_annotation char(100) var;
384
385 dcl get_entry_point_dcl_$emacs entry (char(*), fixed bin, fixed bin, char(*) var, char(32) var, char(100) var);
386
387
388
389
390
391 call get_entry_point_dcl_$emacs (virtualEntry, 0, 0, entry_description, "", entry_annotation);
392 if entry_description = "" then do;
393 call gripe (call_et_$no_entrypoint_info, PROC, "(^a) ^a", entry_annotation, virtualEntry);
394 go to EXIT_call;
395 end;
396
397 on cleanup begin;
398 call call_entry_info_$cleanup(entry_info_ptr);
399 end;
400
401 if entry_annotation = "dcl via parm descriptors" | entry_annotation = "abbrev" then do;
402
403
404
405
406 call call_entry_info_$from_virtual_entry (PROC, virtualEntry,
407 globalOpt.debug, entry_info_ptr, code);
408 if code ^= 0 then do;
409
410 call gripe(code, PROC, "Getting entry parameter descriptors for virtual_entry ^a", virtualEntry);
411 go to EXIT_call;
412 end;
413 end;
414
415 else do;
416
417 entry_description = "dcl " ||
418 reverse (before (reverse (virtualEntry), ">")) || " " || entry_description || ";";
419
420 call call_entry_info_$from_declaration (PROC, virtualEntry, entry_description,
421 globalOpt.debug, entry_info_ptr, code);
422 if code ^= 0 then do;
423 call gripe(code, PROC, "Calling call_entry_info_$from_declaration.");
424 go to EXIT_call;
425 end;
426 end;
427
428 if ei.parm_count <= eiParmCountNotDetermined then do;
429
430
431
432 call gripe(call_et_$no_entrypoint_info, PROC, "Could not determine parameter count from entry sequence.");
433 go to EXIT_call;
434 end;
435
436 if ei.options_variable then do;
437
438
439
440 call argValueGetCount(globalOpt.debug);
441 ei.parm_count = argValueCount;
442 end;
443 %page;
444
445
446
447
448
449
450
451
452
453
454
455 dcl 1 source structure aligned based,
456 2 argP ptr,
457 2 argL fixed bin(21),
458 2 argOpt,
459 3 dir fixed bin(3),
460 3 ret bit (1),
461 3 fmt fixed bin(3),
462 3 xtra fixed bin(2),
463 3 meta fixed bin(2),
464 3 dcl char(100) var,
465
466 3 id char(20) var,
467 3 M fixed bin(24),
468 3 L fixed bin(24),
469 3 L_id char(20) var,
470 2 ad,
471 3 desc like target.desc aligned,
472 3 given bit(1) aligned,
473 3 M_id char(20) var,
474
475
476
477 2 argXref,
478 3 L_idX fixed bin,
479 3 pad fixed bin;
480
481 dcl (DIRunset init(0), DIRin init(1), DIRinout init(2), DIRout init(3), DIRignore init(4))
482 fixed bin(3) int static options(constant);
483 dcl 1 DIR int static options(constant),
484 2 name (0:4) char(10) var init("", "-input", "-inout", "-output", "-outignore" ),
485 2 abbr (0:4) char( 7) var init("", "-in", "-io", "-out", "-ignore" ),
486 2 tiny (0:4) char( 3) var init("", "-i", "", "-o", "-ig" );
487
488 dcl (FMTunset init(0), FMTcode init(1), FMTdate init(2), FMTtime init(3), FMTdate_time init(4))
489 fixed bin(3) int static options(constant);
490 dcl 1 FMT int static options(constant),
491 2 name (0:4) char(10) var init("", "-code", "-date", "-time", "-date_time"),
492 2 abbr (0:4) char(5) var init("", "-cd", "-dt", "-tm", ""),
493 2 kywd (0:4) char(9) init("", "", "date", "time", "date_time");
494
495 dcl (METAunset init(0), METAdcl init(1), METAaddr init(2))
496 fixed bin(2) int static options(constant);
497 dcl 1 META int static options(constant),
498 2 name (0:2) char(5) var init("", "-dcl", "-addr"),
499 2 abbr (0:2) char(8) var init("", "-declare", "");
500
501
502 dcl (XTRAunset init(0), XTRAall init(1), XTRAoctal init(2)) fixed bin(2) int static options(constant);
503 dcl 1 XTRA int static options(constant),
504 2 name (0:2) char(8) var init("", "-all", "-octal"),
505 2 abbr (0:2) char(8) var init("", "-a", "-oc");
506
507 dcl Lunset init(-1) fixed bin(24) int static options(constant);
508 %page;
509 dcl 1 target structure aligned based,
510
511
512
513
514
515
516
517
518 2 descP ptr,
519 2 desc,
520 3 fcnReturnValue bit(1) aligned,
521 3 type fixed bin,
522 3 aligned bit(1) aligned,
523 3 size fixed bin(24),
524 3 scale fixed bin,
525 3 dimensionsCount fixed bin,
526
527
528
529 2 dcl char(100) var,
530 2 storage,
531 3 case fixed bin,
532 3 wordCount fixed bin(24),
533 3 P ptr,
534 3 modifiedDesc aligned like arg_descriptor,
535
536 3 dcl_desc_bv bit(36) aligned;
537
538 dcl (CASEnumeric init(1), CASEpointer init(2), CASEentry init(3),
539 CASEarea init(4), CASEstring init(5), CASEreturnsStar init(6))
540 fixed bin int static options(constant);
541 dcl CASEname (6) init("numeric", "pointer", "entry", "area", "string", "returns_star") char(20) var;
542
543 dcl SizeStar fixed bin (24) int static options (constant) init (16777215);
544
545
546
547
548 argCase:
549 proc (dtype) returns (fixed bin(3) unsigned);
550
551 dcl dtype fixed bin;
552
553 if numeric_dtype(dtype) then return(CASEnumeric);
554 else if string_dtype(dtype) then return(CASEstring);
555 else if (dtype = pointer_dtype) then return(CASEpointer);
556 else if (dtype = entry_dtype) then return(CASEentry);
557 else if (dtype = area_dtype) then return(CASEarea);
558
559
560
561 else return(0);
562
563 end argCase;
564 %page;
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587 xxx
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629 %page;
630
631
632
633
634
635
636
637
638 if globalOpt.debug >= 5 then
639 call ioa_ ("Task 4 begins...");
640
641 dcl (lP, sP, tP) ptr init(null);
642 dcl 1 s (ei.parm_count) aligned like source based(sP);
643
644 dcl 1 t (ei.parm_count) aligned like target based(tP);
645
646
647 dcl 1 l aligned based(lP),
648 2 header like arg_list.header,
649 2 argP (ei.parm_count) ptr,
650 2 descP (ei.parm_count) ptr;
651
652 dcl 1 auto_l aligned automatic,
653 2 header like arg_list.header;
654
655 dcl parmI fixed bin;
656 dcl refI fixed bin;
657
658 dcl areaP ptr;
659 areaP = ei.areaP;
660
661 if ei.parm_count > 0 then do;
662 sP = allocate(areaP, size(s));
663 tP = allocate(areaP, size(t));
664 lP = allocate(areaP, size(l));
665 end;
666 else lP = addr(auto_l);
667
668
669
670
671
672
673 if globalOpt.debug >= 5 then
674 call ioa_ ("Task 5 begins...");
675
676 unspec(l) = ZEROb;
677
678 l.call_type = Interseg_call_type;
679 l.arg_count = ei.parm_count;
680 l.desc_count = ei.parm_count;
681
682 %page;
683
684
685
686
687
688 if globalOpt.debug >= 5 then
689 call ioa_ ("Task 6 begins...");
690
691 dcl 1 charStarUnal_Descriptor aligned int static options(constant),
692 2 flag bit (1) unal init(T),
693 2 type fixed bin (6) unsigned unal init(char_dtype),
694 2 packed bit (1) unal init(T),
695 2 number_dims fixed bin (4) unsigned unal init(0),
696 2 size fixed bin (24) unsigned unal init(SizeStar);
697
698 if tP ^= null then do;
699 unspec(t) = ZEROb;
700
701 if ^ei.options_variable then do;
702 t(*).descP = entry_info.descriptor_ptrs(*);
703
704
705 if globalOpt.debug >= 3 then call ioa_(""); debug
706
707 do parmI = lbound(t,1) to hbound(t,1);
708 call get_entry_parm_info(parmI, ei, t(parmI), globalOpt.debug);
709 end;
710 end;
711 else do;
712 t(*).descP = addr(charStarUnal_Descriptor);
713 t(*).desc.type = char_dtype;
714 t(*).desc.size = SizeStar;
715 t(*).dcl = "char(*)";
716 end;
717 end;
718 %page;
719
720
721
722
723
724
725
726
727
728
729
730
731 if globalOpt.debug >= 5 then
732 call ioa_ ("Task 7 begins...");
733
734 dcl 1 src aligned like source based(addr(s(parmI)));
735 dcl 1 targ aligned like target based(addr(t(parmI)));
736
737 if sP ^= null then
738 HAVE_ARGUMENTS:
739 do;
740 unspec(s) = ZEROb;
741 s(*).argP = null();
742 s(*).M, s(*).L, s(*).L_idX = Lunset;
743
744 ARG_VALUES_LOOP:
745 do parmI = lbound(s,1) to hbound(s,1);
746
747 if ei.function & (parmI = ei.parm_count) then
748 src.id = "retValue";
749 else src.id = "parm" || int2digits(parmI);
750
751
752
753
754 Note
755
756
757
758
759
760 if argsRemain() then
761 ARGS_REMAIN: do;
762 call argValue(parmI, src, globalOpt, code);
763
764
765
766 if code ^= 0 then do;
767 call gripe(code, PROC, "No argument value for: dcl ^a ^a", src.id, targ.dcl);
768 go to EXIT_call;
769 end;
770
771
772 dcl 1 parmDesc aligned like arg_descriptor based(targ.descP);
773
774
775 dcl 1 d aligned like target.desc based(dP);
776 dcl dP ptr;
777 dP = addr(targ.desc);
778
779 if (src.fmt = FMTcode) then
780 if substr(src.id,1,length("parm")) = "parm" then
781 substr(src.id,1,length("parm")) = "code";
782 else if src.id = "retValue" then
783 src.id = "retCode";
784
785
786 dcl arg_desc_bv bit(36) aligned;
787 dcl call_scalar_dcl_ entry (ptr, char(*), uns fixed bin(3), char(256) var, bit(36) aligned, char(*) var,
788 fixed bin(35));
789
790
791 dcl 1 pointer_Descriptor aligned int static options(constant),
792 2 flag bit (1) unal init(T),
793 2 type fixed bin (6) unsigned unal init(pointer_dtype),
794 2 packed bit (1) unal init(F),
795 2 number_dims fixed bin (4) unsigned unal init(0),
796 2 size fixed bin (24) unsigned unal init(0);
797
798
799 if src.meta = METAaddr & length(src.argOpt.dcl) > 0 then do;
800 if ei.options_variable then do;
801 targ.descP = addr(pointer_Descriptor);
802 targ.desc.type = pointer_dtype;
803 targ.desc.aligned = T;
804 targ.dcl = "ptr";
805 end;
806 else if ^((d.type = pointer_dtype) & (d.dimensionsCount = 0)) then do;
807 call gripe(error_table_$bad_arg, PROC,
808 "-addr argument given for non-pointer variable: dcl ^a ^a;", src.id, targ.dcl);
809 go to EXIT_call;
810 end;
811
812 call call_scalar_dcl_ (areaP, "dcl " || src.argOpt.id || " " || src.argOpt.dcl || ";",
813 globalOpt.debug, "", arg_desc_bv, src.ad.M_id, code);
814 if code ^= 0 then do;
815 call gripe(code, PROC, "DECLARATION error: -addr ""^a"" ", src.argOpt.dcl);
816 go to EXIT_call;
817 end;
818 call decode_descriptor(addr(arg_desc_bv), src.ad.desc);
819 if ^supported_by_call_dtype(src.ad.desc.type) then do;
820
821
822
823
824 call gripe(error_table_$bad_arg, PROC,
825 "DECLARATION not supported by call: -addr ""^a"" ", src.argOpt.dcl);
826 go to EXIT_call;
827 end;
828 src.ad.given = T;
829 dP = addr(src.ad.desc);
830 end;
831
832
833 if src.meta = METAdcl & length(src.argOpt.dcl) > 0 then do;
834 dcl dcl_id char(20) var;
835 call call_scalar_dcl_ (areaP, "dcl " || src.argOpt.id || " " || src.argOpt.dcl || ";",
836 globalOpt.debug, "", targ.dcl_desc_bv, dcl_id, code);
837 if code ^= 0 then do;
838 call gripe(code, PROC, "DECLARATION error: -dcl ""^a"" ", src.argOpt.dcl);
839 go to EXIT_call;
840 end;
841 if dcl_id ^= "" then do;
842 call gripe(call_et_$bad_declaration, PROC, "invalid size: -dcl ""^a"" ", src.argOpt.dcl);
843 go to EXIT_call;
844 end;
845 call decode_descriptor(addr(targ.dcl_desc_bv), targ.desc);
846 if ^supported_by_call_dtype(targ.desc.type) then do;
847
848 call gripe(error_table_$bad_arg, PROC,
849 "DECLARATION not supported by call: -dcl ""^a"" ", src.argOpt.dcl);
850 go to EXIT_call;
851 end;
852 targ.descP = addr(targ.storage.dcl_desc_bv);
853 targ.dcl = src.argOpt.dcl;
854 end;
855
856
857 if src.fmt = FMTcode then do;
858 if ^((d.type = FIXED_BIN) & ((d.size = 35 | d.size = 17)) &
859 (d.scale = 0) & d.aligned & (d.dimensionsCount = 0)) then do;
860 call gripe(error_table_$bad_arg, PROC,
861 "-code argument given for non-status code parameter: dcl ^a ^a;", src.id, targ.dcl);
862 go to EXIT_call;
863 end;
864 end;
865
866
867 if src.fmt = FMTdate_time | src.fmt = FMTdate | src.fmt = FMTtime then do;
868 if ^((d.type = real_fix_bin_2_dtype) & (d.size = 71) &
869 (d.scale = 0) & d.aligned & (d.dimensionsCount = 0)) then do;
870 call gripe(error_table_$bad_arg, PROC,
871 "^a argument given for non-clock parameter: dcl ^a ^a;",
872 FMT.name(src.fmt), src.id, targ.dcl);
873 go to EXIT_call;
874 end;
875 end;
876
877
878 if src.M ^= Lunset then do;
879 if ^star_extent_dtype(d.type) then do;
880 call gripe (error_table_$bad_arg, PROC,
881 "-max_length ^d given^[ with -addr ""^a""^;^s^] for data type
882 which is not a string or an area: dcl ^a ^a;",
883 src.M, src.ad.given, src.dcl, src.id, targ.dcl);
884 go to EXIT_call;
885 end;
886 if ^(d.size = SizeStar) then do;
887 call gripe (error_table_$bad_arg, PROC,
888 "-max_length ^d given^[ with -addr ""^a""^;^s^] without star extent: dcl ^a ^a;",
889 src.M, src.ad.given, src.dcl, src.id, targ.dcl);
890 go to EXIT_call;
891 end;
892 end;
893
894
895 if src.L ^= Lunset then do;
896 if ^string_dtype(d.type) then do;
897 call gripe (error_table_$bad_arg, PROC,
898 "-length ^d given^[ with -addr ""^a""^;^s^] for non-string: dcl ^a ^a;",
899 src.L, src.ad.given, src.dcl, src.id, targ.dcl);
900 go to EXIT_call;
901 end;
902 end;
903
904
905 if length(src.L_id) > 0 then do;
906 if ^string_dtype(d.type) then do;
907 call gripe (error_table_$bad_arg, PROC,
908 "-length ^a given^[ with -addr ""^a""^;^s^] for non-string: dcl ^a ^a;",
909 src.L_id, src.ad.given, src.dcl, src.id, targ.dcl);
910 go to EXIT_call;
911 end;
912 end;
913 end ARGS_REMAIN;
914
915 else if ^targ.desc.fcnReturnValue then do;
916
917 call gripe(error_table_$noarg, PROC, "No argument value for: parm^d ^a", parmI, targ.dcl);
918 go to EXIT_call;
919 end;
920
921 end ARG_VALUES_LOOP;
922 end HAVE_ARGUMENTS;
923 %page;
924
925
926
927
928
929
930
931
932
933
934 if sP ^= null then
935 HAVE_SOURCE_SPECS:
936 do;
937 SOURCE_SPECS_LOOP:
938 do parmI = lbound(s,1) to hbound(s,1);
939 if length(src.ad.M_id) > 0 then
940 ADDR_DECL_REFERENCE:
941 do;
942 refI = sourceWithID(src.ad.M_id);
943 if refI > 0 then do;
944 if ^parmIsFixedBin(s(refI), t(refI)) | s(refI).ad.given then do;
945 call gripe (error_table_$bad_arg, PROC,
946 "-addr ""^a"" references arg_value not fixed binary (unsuitable as a length): dcl ^a ^a;",
947 src.dcl, src.id, targ.dcl);
948 go to EXIT_call;
949 end;
950 else if s(refI).dir > DIRinout then do;
951 call gripe (error_table_$bad_arg, PROC,
952 "-addr ""^a"" references arg_value not an input value: dcl ^a ^a; (^a)",
953 src.dcl, s(refI).id, t(refI).dcl, DIR.name(s(refI).dir));
954 go to EXIT_call;
955 end;
956 else if refI = parmI then do;
957 call gripe (error_table_$bad_arg, PROC,
958 "-addr ""^a"" references its own parameter: dcl ^a ^a;",
959 src.dcl, src.id, targ.dcl);
960 go to EXIT_call;
961 end;
962 else do;
963 src.M = argFixedBinValue(s(refI), t(refI), null());
964 if src.M = SizeStar then do;
965 call gripe (error_table_$bad_conversion, PROC,
966 "-addr ""^a"" references an arg_value with -id ^a not convertible to fixed bin(24)",
967 src.dcl, src.ad.M_id);
968 go to EXIT_call;
969 end;
970 src.ad.desc.size = src.M;
971 end;
972 end;
973 else do;
974 call gripe (error_table_$oldnamerr, PROC,
975 "-addr ""^a"" references an ID not found on any other arg_value specification.", src.dcl);
976 go to EXIT_call;
977 end;
978 end ADDR_DECL_REFERENCE;
979
980 if length(src.L_id) > 0 then
981 LENGTH_REFERENCE:
982 do;
983 refI = sourceWithID(src.L_id);
984 if refI > 0 then do;
985 if ^parmIsFixedBin(s(refI), t(refI)) then do;
986 call gripe (error_table_$bad_arg, PROC,
987 "-length ^a is not fixed binary (unsuitable as a length): dcl ^a ^a;",
988 src.L_id, src.id, targ.dcl);
989 go to EXIT_call;
990 end;
991 else if refI = parmI then do;
992 call gripe (error_table_$bad_arg, PROC,
993 "-length ^a references its own parameter: dcl ^a ^a;",
994 src.L_id, src.id, targ.dcl);
995 go to EXIT_call;
996 end;
997 else
998 src.argXref.L_idX = refI;
999 end;
1000 else do;
1001 call gripe (error_table_$oldnamerr, PROC,
1002 "-length ^a references an ID not found on any other arg_value specification.", src.L_id);
1003 go to EXIT_call;
1004 end;
1005 end LENGTH_REFERENCE;
1006
1007 end SOURCE_SPECS_LOOP;
1008 end HAVE_SOURCE_SPECS;
1009 %page;
1010
1011
1012
1013
1014
1015
1016
1017 if globalOpt.debug >= 5 then
1018 call ioa_ ("Task 8 begins...");
1019
1020 dcl 1 parmSummary aligned,
1021 2 parmsNotSupported fixed bin,
1022 2 convertFailed fixed bin,
1023
1024 2 totalStorageNeeded fixed bin(35);
1025
1026
1027 if tP ^= null then do;
1028 parmSummary = 0;
1029 do parmI = lbound(t,1) to hbound(t,1);
1030 call argAssign (parmI, s(parmI), t(parmI), globalOpt.debug,
1031 l.argP(parmI), l.descP(parmI), areaP, parmSummary);
1032 end;
1033 if ^((parmSummary.parmsNotSupported = 0) & (parmSummary.convertFailed = 0)) then
1034 go to EXIT_call;
1035
1036 end;
1037 %page;
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047 if globalOpt.debug >= 5 then
1048 call ioa_ ("Task 9 begins...");
1049
1050 dcl output char(3000) varying; debug
1051 dcl outputD char(80) varying;
1052 dcl outPrefix char(100) varying;
1053
1054 outPrefix = ei.entrypoint.nameString;
1055
1056 if globalOpt.debug >= 2 & tP ^= null() then do;
1057
1058
1059 call ioa_ ("
1060 do parmI = lbound(t,1) to hbound(t,1);
1061 call debugOutputArg(parmI, s(parmI), t(parmI), l.argP(parmI), l.descP(parmI), command, output, outputD);
1062 call ioa_(" ^va @ ^p = ^a", maxlength(s(parmI).id), s(parmI).id, l.argP(parmI), output);
1063 call ioa_(" ^vx desc @ ^p^42t^a", maxlength(s(parmI).id)-length("desc "), l.descP(parmI), outputD);
1064 end;
1065 end;
1066 else if globalOpt.debug >= 2 then
1067 call ioa_ ("
1068
1069 if globalOpt.debug > 0 then do; debug
1070 call ioa_ ("
1071 outPrefix = NL || "
1072 end;
1073 else do;
1074 outPrefix = "
1075 if command then call ioa_("");
1076 end;
1077
1078 dcl cu_$generate_call entry (entry, ptr);
1079
1080 call cu_$generate_call (ei.entryVar, addr (l));
1081
1082 %page;
1083
1084
1085
1086
1087
1088
1089
1090
1091 if globalOpt.debug >= 5 then
1092 call ioa_ ("Task 10 begins...");
1093
1094
1095 do parmI = 1 to ei.parm_count;
1096 refI = s(parmI).L_idX;
1097 if refI ^= Lunset then
1098 s(parmI).L = argFixedBinValue(s(refI), t(refI), l.argP(refI));
1099 end;
1100
1101 if command then do;
1102 dcl outS bit(1) aligned;
1103 do parmI = 1 to ei.parm_count;
1104 if globalOpt.xtra = XTRAoctal then src.xtra = XTRAoctal;
1105
1106 outS = (globalOpt.xtra = XTRAall) | (src.xtra = XTRAoctal ) |
1107 (src.dir >= DIRinout & src.dir < DIRignore) |
1108 targ.desc.fcnReturnValue;
1109 if (src.dir = DIRin) | (src.dir = DIRignore) then outS = F;
1110
1111 if outS then do;
1112 call convertOutputArg(parmI, s(parmI), t(parmI), l.argP(parmI), l.descP(parmI), command, output);
1113 call ioa_("^a ^va ^a", outPrefix, maxlength(src.id), src.id, output);
1114 outPrefix = "";
1115 end;
1116 end;
1117 end;
1118 else do;
1119 do parmI = 1 to ei.parm_count;
1120 if s(parmI).dir = DIRout & s(parmI).fmt = FMTcode then do;
1121 call convertOutputArg(parmI, s(parmI), t(parmI), l.argP(parmI), l.descP(parmI), command, af_ret);
1122 if af_ret ^= "" then go to EXIT_call;
1123 end;
1124 end;
1125 do parmI = 1 to ei.parm_count;
1126 if s(parmI).ret & (s(parmI).fmt ^= FMTcode) then do;
1127 call convertOutputArg(parmI, s(parmI), t(parmI), l.argP(parmI), l.descP(parmI), command, af_ret);
1128 go to EXIT_call;
1129 end;
1130 end;
1131 parmI = ei.parm_count;
1132 if (parmI > 0) then
1133 if targ.fcnReturnValue & (s(parmI).dir ^= DIRignore) then
1134 call convertOutputArg(parmI, s(parmI), t(parmI), l.argP(parmI), l.descP(parmI), command, af_ret);
1135 end;
1136
1137 EXIT_call:
1138 call call_entry_info_$cleanup(entry_info_ptr);
1139 return;
1140 %page;
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155 get_entry_parm_info:
1156 proc (i, e, t, debug);
1157
1158 dcl i fixed bin;
1159 dcl 1 e aligned like entry_info_header;
1160
1161 dcl 1 t aligned like target;
1162 dcl debug fixed bin(3) unsigned; debug
1163
1164 call decode_descriptor(t.descP, t.desc);
1165 if ^supported_by_pl1_dtype(t.desc.type) then do;
1166 t.dcl = "";
1167 return;
1168 end;
1169
1170 t.desc.fcnReturnValue = ((i = ei.parm_count) & ei.function);
1171 t.dcl = descriptorString (t.descP);
1172
1173 if debug >= 3 then
1174 if t.desc.fcnReturnValue
1175 then call ioa_ (" returns(^a);", t.dcl);
1176 else call ioa_ (" dcl parm^a ^a;", int2digits(i), t.dcl);
1177
1178 end get_entry_parm_info;
1179
1180
1181
1182
1183
1184
1185
1186
1187 decode_descriptor:
1188 proc (descP, desc);
1189
1190 dcl descP ptr;
1191 dcl 1 desc aligned like target.desc;
1192
1193 dcl decode_descriptor_ entry (ptr, fixed bin, fixed bin, bit (1) aligned, fixed bin, fixed bin (24), fixed bin);
1194
1195 dcl packed bit (1) aligned;
1196
1197 call decode_descriptor_(descP, 0, desc.type, packed, desc.dimensionsCount, desc.size, desc.scale);
1198 desc.aligned = ^packed;
1199
1200 end decode_descriptor;
1201
1202
1203
1204
1205
1206
1207
1208
1209 sourceWithID:
1210 proc (idNeeded) returns(fixed bin);
1211
1212 dcl idNeeded char(20) var;
1213 dcl i fixed bin;
1214
1215 do i = lbound(s,1) to hbound(s,1);
1216 if s(i).id = idNeeded then
1217 return(i);
1218 end;
1219 return(0);
1220 end sourceWithID;
1221
1222 %page;
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247 argAssign:
1248 proc (i, src, targ, debugI, listArgP, listDescP, areaP, pl);
1249
1250 dcl i fixed bin;
1251 dcl 1 src structure aligned like source;
1252 dcl 1 targ structure aligned like target;
1253 dcl debugI fixed bin(3) unsigned; debug
1254 dcl listArgP ptr;
1255 dcl listDescP ptr;
1256 dcl areaP ptr;
1257 dcl 1 pl structure aligned like parmSummary;
1258
1259 dcl 1 parmDesc aligned like arg_descriptor based(targ.descP);
1260
1261
1262 dcl 1 d aligned like target.desc based(dP);
1263 dcl dP ptr;
1264
1265 if src.ad.given then
1266 dP = addr(src.ad.desc);
1267 else dP = addr(targ.desc);
1268
1269
1270
1271
1272 if ^supported_by_call_dtype(d.type) then do;
1273 ASSIGN_bad_type:
1274 if d.type = structure_dtype then
1275 call gripe (call_et_$structure_unsupported, PROC, "dcl 1 ^a ^a;^[ -addr ""^a""^;^s^]",
1276 src.id, substr(targ.dcl,2), src.ad.given, src.dcl);
1277 else call gripe (call_et_$parameter_type_unsupported, PROC, "^a (^d): dcl ^a ^a;^[ -addr ""^a""^;^s^]",
1278 pl1_dtype_name(d.type), d.type, src.id, targ.dcl, src.ad.given, src.dcl);
1279 go to ASSIGN_unsupported;
1280 end;
1281 if d.dimensionsCount > 0 then do;
1282 call gripe(call_et_$array_unsupported, PROC,
1283 "dcl ^a ^a;^[ -addr ""^a""^;^s^]", src.id, targ.dcl, src.ad.given, src.dcl);
1284 go to ASSIGN_unsupported;
1285 end;
1286
1287 targ.case = argCase(d.type);
1288 if targ.case = 0 then go to ASSIGN_bad_type;
1289
1290 if d.fcnReturnValue & targ.case = CASEstring & d.size = SizeStar & ^src.ad.given then do;
1291
1292 targ.case = CASEreturnsStar;
1293 targ.storage.wordCount = 0;
1294 targ.storage.P = null;
1295 go to ASSIGN_for(targ.case);
1296 end;
1297
1298 dcl octHex bit(1) aligned init(F);
1299 dcl sourceBits bit(200) varying aligned;
1300
1301
1302
1303 if (fixed_bin_dtype(d.type) | bit_string_dtype(d.type)) then
1304 octHex = T;
1305
1306
1307 dcl desiredSize fixed bin(24);
1308 desiredSize = d.size;
1309
1310 if star_extent_dtype(d.type) & d.size = SizeStar then do;
1311 if src.M ^= Lunset then xxx
1312 desiredSize = src.M;
1313 else if char_string_dtype(d.type) & src.argL > 0 then
1314 desiredSize = src.argL;
1315 else if bit_string_dtype(d.type) & src.argL > 0 then do;
1316 if octHex & oct_or_hex_source(srcArg, sourceBits) then
1317 desiredSize = length(sourceBits);
1318 else desiredSize = src.argL;
1319 end;
1320 end;
1321 if star_extent_dtype(d.type) & desiredSize = SizeStar then do;
1322 call gripe(call_et_$star_extent_unresolved, PROC,
1323 "Use -max_length M to give a size: dcl ^a ^a; ^[-addr ""^a""^;^s^]",
1324 src.id, targ.dcl, src.ad.given, src.dcl);
1325 go to ASSIGN_unsupported;
1326 end;
1327
1328
1329 dcl code fixed bin(35);
1330 call argStorageWords (d.type, d.aligned, desiredSize, targ.storage.wordCount, code);
1331 if code ^= 0 then do;
1332 call gripe (code, PROC, "Unsupported storage type: ^a (^d): dcl ^a ^a;^[ -addr ""^a""^;^s^]",
1333 pl1_dtype_name(d.type), d.type, src.id, targ.dcl, src.ad.given, src.dcl);
1334 go to ASSIGN_unsupported;
1335 end;
1336
1337 targ.storage.P = allocate(areaP, (targ.storage.wordCount));
1338
1339
1340 dcl srcArg char(src.argL) based(src.argP);
1341
1342 dcl emptyString char(0) int static options(constant) init("");
1343
1344 if src.dir >= DIRout then do;
1345 src.argP = addr(emptyString);
1346 src.argL = length(emptyString);
1347 end;
1348
1349 go to ASSIGN_for(targ.case);
1350 %page;
1351
1352 ASSIGN_for (CASEpointer):
1353
1354 dcl cv_ptr_ entry (char(*), fixed bin(35)) returns(ptr);
1355 dcl convPtr ptr;
1356 dcl assignPtr ptr based(targ.storage.P);
1357 dcl assignPtrPacked ptr unal based(targ.storage.P);
1358
1359 if src.argL = 0 then
1360 convPtr = null();
1361 else do;
1362 convPtr = cv_ptr_(srcArg, code);
1363 if code ^= 0 then go to ASSIGN_failed;
1364 end;
1365 if targ.desc.aligned then
1366 assignPtr = convPtr;
1367 else assignPtrPacked = convPtr;
1368 listDescP = targ.descP;
1369 go to ASSIGN_ok;
1370
1371
1372 ASSIGN_for (CASEentry):
1373
1374 dcl cv_entry_ entry (char(*), ptr, fixed bin(35)) returns(entry);
1375 dcl cu_$make_entry_value entry (ptr, entry);
1376 dcl convEntry entry variable options(variable);
1377 dcl assignEntry entry variable options(variable) based(targ.storage.P);
1378
1379 if src.argL = 0 then
1380 call cu_$make_entry_value (null(), convEntry);
1381
1382 else do;
1383 convEntry = cv_entry_(srcArg, null(), code);
1384 if code ^= 0 then go to ASSIGN_failed;
1385 end;
1386 assignEntry = convEntry;
1387 listDescP = targ.descP;
1388 go to ASSIGN_ok;
1389
1390
1391 ASSIGN_for (CASEnumeric):
1392 if src.dir <= DIRinout & src.fmt = FMTcode & src.argL > 0 then do;
1393
1394 dcl statusCodeE entry variable;
1395 dcl statusCodeP ptr;
1396 dcl statusCode fixed bin(35) aligned based(statusCodeP);
1397 dcl assignCode fixed bin(35) aligned based(targ.storage.P);
1398
1399 statusCodeE = cv_entry_(srcArg, null(), code);
1400 if code ^= 0 then go to ASSIGN_failed;
1401 statusCodeP = codeptr(statusCodeE);
1402 assignCode = statusCode;
1403 end;
1404
1405 else if src.dir <= DIRinout & ((src.fmt = FMTdate_time) | (src.fmt = FMTdate) | (src.fmt = FMTtime)) then do;
1406
1407 dcl clockN fixed bin(71) aligned based(targ.storage.P);
1408 dcl convert_date_to_binary_ entry (char(*), fixed bin(71), fixed bin(35));
1409
1410 call convert_date_to_binary_(srcArg, clockN, code);
1411 if code ^= 0 then go to ASSIGN_failed;
1412 end;
1413
1414 else do;
1415 call assign(srcArg, octHex, targ.P, d.type, d.aligned, d.size, d.scale, code);
1416 if code ^= 0 then go to ASSIGN_failed;
1417 end;
1418 listDescP = targ.descP;
1419 go to ASSIGN_ok;
1420
1421
1422 ASSIGN_for (CASEarea):
1423
1424 dcl 1 ai aligned like area_info;
1425 dcl assignArea area(desiredSize) based(targ.storage.P);
1426 dcl define_area_ entry (ptr, fixed bin(35));
1427
1428 unspec(ai) = ZEROb;
1429 ai.version = area_info_version_1;
1430 ai.control.zero_on_free = T;
1431 ai.owner = PROC;
1432 ai.size = desiredSize;
1433 ai.areap = targ.storage.P;
1434 call define_area_ (addr(ai), code);
1435 if code ^= 0 then go to ASSIGN_area_failed;
1436
1437 if ^src.ad.given & d.size = SizeStar then do;
1438 targ.modifiedDesc = parmDesc;
1439 targ.modifiedDesc.size = desiredSize;
1440 listDescP = addr(targ.modifiedDesc);
1441 end;
1442 else if src.ad.given then do;
1443 listDescP = targ.descP;
1444 src.ad.desc.size = desiredSize;
1445 end;
1446 else listDescP = targ.descP;
1447 go to ASSIGN_ok;
1448
1449
1450 ASSIGN_for (CASEstring):
1451 call assign(srcArg, octHex, targ.P, d.type, d.aligned, desiredSize, 0, code);
1452 if ^src.ad.given & d.size = SizeStar then do;
1453 targ.modifiedDesc = parmDesc;
1454 targ.modifiedDesc.size = desiredSize;
1455 listDescP = addr(targ.modifiedDesc);
1456 end;
1457 else listDescP = targ.descP;
1458 go to ASSIGN_ok;
1459
1460
1461 ASSIGN_for (CASEreturnsStar): xxx
1462 unspec(targ.modifiedDesc) = ZEROb;
1463 listDescP = addr(targ.modifiedDesc);
1464 targ.storage.P = null;
1465 listArgP = addr(targ.storage.P);
1466 go to ASSIGN_debug;
1467
1468
1469 ASSIGN_ok:
1470 if src.ad.given then
1471 listArgP = addr(targ.P);
1472 else if varying_string_dtype(d.type) then
1473 listArgP = addrel(targ.P, 1);
1474 else listArgP = targ.P;
1475 ASSIGN_debug:
1476 if debugI >= 4 then
1477 call ioa_(" ^va @ ^p ^2d word^[^;s^]", maxlength(src.id), src.id, listArgP, targ.storage.wordCount,
1478 targ.storage.wordCount = 1);
1479 return;
1480
1481 ASSIGN_failed:
1482 call gripe(code, PROC, "Converting ""^a"" ^a to: dcl ^a ^a;^[ -addr ""^a""^;^s^]",
1483 srcArg, FMT.name(src.fmt), src.id, targ.dcl, src.ad.given, src.dcl);
1484 pl.convertFailed = pl.convertFailed + 1;
1485 return;
1486
1487 ASSIGN_area_failed:
1488 call gripe(code, PROC, "Emptying area: ^a -id ^a (dcl: ^a)^[ -addr ""^a""^;^s^]",
1489 DIR.name(src.dir), src.id, targ.dcl, src.ad.given, src.dcl);
1490 pl.convertFailed = pl.convertFailed + 1;
1491 return;
1492
1493 ASSIGN_unsupported:
1494 pl.parmsNotSupported = pl.parmsNotSupported + 1;
1495 return;
1496
1497 end argAssign;
1498
1499
1500 argStorageBits:
1501 proc (dtype, daligned, dsize) returns(fixed bin(24));
1502
1503 dcl dtype fixed bin;
1504 dcl daligned bit(1) aligned;
1505 dcl dsize fixed bin(24);
1506
1507 dcl code fixed bin(35);
1508 dcl count fixed bin(24);
1509
1510 dcl boundary fixed bin(2) unsigned;
1511
1512 call storage_for_pl1_dtype(dtype, ^daligned, dsize, boundary, count, code);
1513 if code = 0 then do;
1514 if boundary = BOUNDARY.Word then
1515 count = count * bits_per_word;
1516 else if boundary = BOUNDARY.Byte then
1517 count = count * bits_per_character;
1518 end;
1519 else count = 36;
1520
1521
1522 return (count);
1523 end argStorageBits;
1524
1525
1526 argStorageWords:
1527 proc (dtype, daligned, dsize, count, code);
1528
1529 dcl dtype fixed bin;
1530 dcl daligned bit(1) aligned;
1531 dcl dsize fixed bin(24);
1532 dcl count fixed bin(24);
1533 dcl code fixed bin(35);
1534
1535 dcl boundary fixed bin(2) unsigned;
1536
1537 call storage_for_pl1_dtype(dtype, ^daligned, dsize, boundary, count, code);
1538 if code = 0 then do;
1539 if boundary = BOUNDARY.Byte then
1540 count = divide(count+characters_per_word-1, characters_per_word, 24, 0);
1541 else if boundary = BOUNDARY.Bit then
1542 count = divide(count+bits_per_word-1, bits_per_word, 24, 0);
1543 end;
1544
1545 end argStorageWords;
1546 %page;
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564 argFixedBinValue:
1565 proc (src, targ, argP) returns(fixed bin(24));
1566
1567 dcl 1 src aligned like source;
1568 dcl 1 targ aligned like target;
1569 dcl argP ptr;
1570
1571
1572
1573 dcl PACKED fixed bin int static options(constant) init(1);
1574
1575 dcl 1 desc aligned like target.desc;
1576 dcl fbSourceP ptr;
1577 dcl fbAddressedSource ptr based(argP);
1578 dcl value fixed bin(24);
1579
1580 dcl (conversion, size) condition;
1581
1582 if src.ad.given then do;
1583 desc = src.ad.desc;
1584 fbSourceP = fbAddressedSource;
1585 end;
1586 else do;
1587 desc = targ.desc;
1588 fbSourceP = argP;
1589 end;
1590
1591 on conversion begin;
1592 code = error_table_$bad_conversion;
1593 go to EXIT_parm_value;
1594 end;
1595 on size begin;
1596 code = error_table_$size_error;
1597 go to EXIT_parm_value;
1598 end;
1599
1600 if argP = null() then
1601
1602 call assign_ (addr(value), 2*FIXED_BIN, 24, src.argP , 2*char_dtype+PACKED, binary(src.argL,35,0));
1603 else
1604
1605 call assign_ (addr(value), 2*FIXED_BIN, 24, fbSourceP, 2*desc.type + binary(^desc.aligned,1,0), binary(desc.size,35,0));
1606 return(value);
1607
1608 EXIT_parm_value:
1609 if argP = null() then
1610 return(SizeStar);
1611 else do;
1612
1613 call gripe(code, PROC, "Converting bin length value; returning 10 instead.");
1614 return(10);
1615 end;
1616
1617 end argFixedBinValue;
1618
1619
1620 parmIsFixedBin:
1621 proc (src, targ) returns(bit(1) aligned);
1622
1623 dcl 1 src aligned like source;
1624 dcl 1 targ aligned like target;
1625
1626 if src.ad.given then do;
1627 if fixed_bin_dtype(src.ad.desc.type) & src.ad.desc.scale = 0 then return(T);
1628 else return(F);
1629 end;
1630 if fixed_bin_dtype(targ.desc.type) & targ.desc.scale = 0 then return(T);
1631 else return(F);
1632
1633 end parmIsFixedBin;
1634 %page;
1635
1636
1637
1638
1639
1640
1641
1642
1643 dcl FIXED_BIN fixed bin aligned int static options(constant) init(real_fix_bin_1_dtype);
1644 dcl FIXED_BIN_UNS fixed bin aligned int static options(constant) init(real_fix_bin_1_uns_dtype);
1645
1646
1647 dcl ALIGNED bit(1) aligned int static init("1"b) options (constant);
1648 dcl UNALIGNED bit(1) aligned int static init("0"b) options (constant);
1649
1650 assign:
1651 proc( source, octHex, targetP, targetType, targetAligned, targetPrecision, targetScale, code);
1652
1653 dcl source char(*);
1654 dcl octHex bit(1) aligned;
1655 dcl targetP ptr;
1656 dcl targetType fixed bin;
1657 dcl targetAligned bit(1) aligned;
1658
1659 dcl targetPrecision fixed bin(24);
1660
1661 dcl targetScale fixed bin;
1662 dcl code fixed bin(35);
1663
1664 dcl (conversion, overflow, size, underflow) condition;
1665
1666 dcl sourcePacked fixed bin int static options(constant) init(1);
1667 dcl targetPacked fixed bin init(1);
1668
1669
1670 dcl targetL fixed bin(35) init(targetPrecision);
1671
1672
1673 dcl 1 encp aligned like encoded_precision;
1674
1675 if fixed_point_dtype(targetType) then do;
1676 encp.prec = targetPrecision;
1677 encp.scale = targetScale;
1678 unspec(targetL) = unspec(encp);
1679 end;
1680
1681 code = 0;
1682
1683 if targetAligned then targetPacked = 0;
1684
1685 on conversion begin;
1686 code = error_table_$bad_conversion;
1687 go to EXIT_ASSIGN;
1688 end;
1689 on overflow begin;
1690 code = call_et_$overflow_error;
1691 go to EXIT_ASSIGN;
1692 end;
1693 on size begin;
1694 code = error_table_$size_error;
1695 go to EXIT_ASSIGN;
1696 end;
1697 on underflow begin;
1698 code = call_et_$underflow_error;
1699 go to EXIT_ASSIGN;
1700 end;
1701
1702 if octHex then
1703 LOOK_FOR_OCTHEX:
1704 do;
1705 dcl sourceBits bit(200) var;
1706 if oct_or_hex_source(source, sourceBits) then
1707 HAVE_OCTHEX_SOURCE:
1708 do;
1709 if unsigned_dtype(targetType) then
1710 sourceBits = ltrimZeroes(sourceBits);
1711 else if fixed_bin_dtype(targetType) then
1712 OCTHEX_FIXED_BIN:
1713 do;
1714 if length(sourceBits) > targetPrecision then
1715 sourceBits = ltrimZeroes(sourceBits);
1716
1717 if length(sourceBits) > targetPrecision+1 then do;
1718 code = error_table_$size_error;
1719 go to EXIT_ASSIGN;
1720 end;
1721 if length(sourceBits) = targetPrecision+1 then do;
1722
1723
1724 dcl signHolder bit(72) aligned;
1725 dcl signBits bit(targetL-targetPrecision) aligned based(addr(signHolder));
1726 dcl targetBits bit(targetL) aligned based(targetP);
1727
1728 targetL = argStorageBits( targetType, targetAligned, targetPrecision);
1729 sourceBits = substr(sourceBits,2);
1730 signBits = NEG_SIGN_BITS;
1731 sourceBits = signBits || sourceBits;
1732 targetBits = sourceBits;
1733 go to EXIT_ASSIGN;
1734 end;
1735 end OCTHEX_FIXED_BIN;
1736
1737 call assign_(targetP, 2*targetType + targetPacked, targetL,
1738 addr(sourceBits),2*varying_bit_dtype, length(sourceBits));
1739 go to EXIT_ASSIGN;
1740
1741 end HAVE_OCTHEX_SOURCE;
1742 end LOOK_FOR_OCTHEX;
1743
1744 call assign_(targetP, 2*targetType + targetPacked, targetL,
1745 addr(source), 2*char_dtype + sourcePacked, length(source));
1746
1747 EXIT_ASSIGN:
1748 end assign;
1749 %page;
1750
1751
1752
1753
1754
1755
1756 ltrimZeroes:
1757 proc(s) returns(bit(200) varying aligned);
1758 dcl s bit(200) varying aligned;
1759
1760 dcl i fixed bin;
1761 dcl foundOneI fixed bin;
1762
1763 do i = 1 to length(s);
1764 if substr(s,i,1) = "1"b then do;
1765 foundOneI = i;
1766 go to LTRIM;
1767 end;
1768 end;
1769 return(""b);
1770
1771 LTRIM:
1772 return (substr(s,foundOneI));
1773 end ltrimZeroes;
1774
1775
1776 dcl sourceBits bit (200) varying aligned init(""b);
1777
1778 oct_or_hex_source:
1779 proc (s, bv) returns(bit(1) aligned);
1780
1781 dcl s char(*);
1782 dcl bv bit(200) varying aligned;
1783
1784 if index(reverse(s), "3b") = 1 then do;
1785 if verify(s, "01234567") = length(s)-1 then do;
1786 call bitsFromOctal(s, bv);
1787 return (T);
1788 end;
1789 return(F);
1790 end;
1791 if index(reverse(s), "4b") = 1 then do;
1792 if verify(s, "0123456789abcdefABCDEF") = 0 then do;
1793 call bitsFromHex(s, bv);
1794 return (T);
1795 end;
1796 return(F);
1797 end;
1798 return (F);
1799
1800 end oct_or_hex_source;
1801
1802
1803 bitsFromOctal:
1804 proc(s, bv);
1805
1806
1807 dcl s char(*);
1808 dcl bv bit(200) varying aligned;
1809
1810 dcl i fixed bin;
1811 dcl sa (length(s)) char(1) based(addr(s));
1812 dcl oct (8) bit(3) int static options(constant) init(
1813 "000"b, "001"b, "010"b, "011"b, "100"b, "101"b, "110"b, "111"b);
1814
1815 bv = ""b;
1816
1817 do i = 1 to length(s)-length("b3");
1818 bv = bv || oct(index("01234567", sa(i)));
1819 end;
1820 return;
1821
1822
1823 bitsFromHex:
1824 entry(s, bv);
1825
1826 dcl hex (22) bit(4) int static options(constant) init(
1827 "0000"b, "0001"b, "0010"b, "0011"b, "0100"b, "0101"b, "0110"b, "0111"b,
1828 "1000"b, "1001"b, "1010"b, "1011"b, "1100"b, "1101"b, "1110"b, "1111"b,
1829 "1010"b, "1011"b, "1100"b, "1101"b, "1110"b, "1111"b);
1830 bv = ""b;
1831 do i = 1 to length(s)-length("b4");
1832 bv = bv || hex(index("0123456789abcdefABCDEF", sa(i)));
1833 end;
1834 return;
1835
1836 end bitsFromOctal;
1837
1838 %page;
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850 debug
1851
1852
1853
1854
1855
1856
1857 convertOutputArg:
1858 proc (i, src, targ, listArgP, listDescP, command, out);
1859
1860 dcl i fixed bin;
1861 dcl 1 src aligned like source;
1862 dcl 1 targ aligned like target;
1863 dcl listArgP ptr;
1864 dcl listDescP ptr;
1865 dcl command bit(1) aligned;
1866 dcl out char(*) varying;
1867
1868 dcl 1 desc aligned like target.desc;
1869 dcl ioaL fixed bin(21);
1870 dcl outDump char(1000) varying;
1871 dcl packed bit(1) aligned;
1872 dcl parmP ptr init(listArgP);
1873
1874 dcl debugOutput bit(1) aligned init(T);
1875
1876 debugOutput = F;
1877
1878 debugOutputArg:
1879 entry (i, src, targ, listArgP, listDescP, command, out, outD);
1880
1881
1882
1883
1884
1885 dcl outD char(*) varying; Debug
1886
1887 out = "";
1888
1889 if targ.case = CASEreturnsStar then do; xxxxxx
1890 if debugOutput then do;
1891 unspec(desc) = "0"b;
1892 desc.type = pointer_dtype;
1893 desc.aligned = T;
1894 parmP = listArgP;
1895 go to CONV(CASEpointer);
1896 end;
1897 else do;
1898 parmP = parmToPtrAligned(parmP, T);
1899
1900 if parmP ^= null() & varying_string_dtype(targ.desc.type) then
1901 parmP = addrel(parmP, -1);
1902
1903
1904 end;
1905 end;
1906
1907 call decode_descriptor(listDescP, desc);
1908
1909
1910 if src.ad.given then do;
1911 parmP = parmToPtrAligned(parmP, desc.aligned);
1912 if parmP ^= null then
1913 desc = src.ad.desc;
1914 else parmP = listArgP;
1915 end;
1916 else if targ.case ^= CASEreturnsStar then do;
1917 if varying_string_dtype(desc.type) then
1918 parmP = addrel(listArgP, -1);
1919 else parmP = listArgP;
1920 end;
1921
1922 go to CONV(argCase(desc.type));
1923
1924
1925 CONV (CASEnumeric):
1926 if (src.fmt = FMTcode) & (^debugOutput | src.dir <= DIRinout) then do;
1927
1928 dcl codeN fixed bin(35) aligned based(parmP);
1929 dcl shortMsg char(8) aligned;
1930 dcl longMsg char(100) aligned;
1931 dcl codeName char(128) var;
1932
1933 dcl call_status_code_name_ entry (fixed bin(35)) returns(char(128) var);
1934 dcl convert_status_code_ entry (fixed bin(35), char(8) aligned, char(100) aligned);
1935
1936 if codeN ^= 0 then do;
1937 codeName = call_status_code_name_(codeN);
1938 call convert_status_code_(codeN, shortMsg, longMsg);
1939 if length(codeName) > 0 then
1940 out = codeName || " " || rtrim(longMsg);
1941 else out = rtrim(longMsg);
1942 end;
1943 else if command then out = "OK";
1944 else out = "";
1945 end;
1946
1947 else if ((src.fmt = FMTdate_time) | (src.fmt = FMTdate) | (src.fmt = FMTtime)) &
1948 (^debugOutput | src.dir <= DIRinout) then do;
1949
1950 dcl clockN fixed bin(71) aligned based(parmP);
1951 dcl date_time char(250) var;
1952 dcl date_time_$format entry (char(*), fixed bin(71), char(*), char(*)) returns(char(250) var);
1953 dcl (process_default_zone, process_default_lang) char(0) init("") int static options(constant);
1954
1955 date_time = date_time_$format(FMT.kywd(src.fmt), clockN, process_default_zone, process_default_lang);
1956 out = date_time;
1957 end;
1958
1959 else do;
1960
1961 dcl 1 encp aligned like encoded_precision;
1962 dcl sourceL fixed bin(35);
1963
1964 if fixed_point_dtype(desc.type) then do;
1965 encp.prec = desc.size;
1966 encp.scale = desc.scale;
1967 unspec(sourceL) = unspec(encp);
1968 end;
1969 else sourceL = desc.size;
1970 call assign_(addr(out), 2*varying_char_dtype, maxlength(out),
1971 parmP, desc.type*2 + binary(^desc.aligned), sourceL);
1972 out = ltrim(out);
1973 end;
1974 go to CONV_return;
1975
1976
1977 CONV (CASEstring):
1978
1979 dcl bitS bit(sourceL) based(parmP);
1980 dcl bitV bit(sourceL) varying based(parmP);
1981 dcl varS bit(1) aligned init(F);
1982
1983 if src.L ^= Lunset then
1984 sourceL = src.L;
1985 else sourceL = desc.size;
1986
1987 if varying_string_dtype(desc.type) then do;
1988 dcl lengthWord fixed bin(24) aligned based(parmP);
1989 varS = T;
1990 sourceL = min(sourceL, lengthWord);
1991 end;
1992
1993 if sourceL = SizeStar then note
1994 out = "[STRING of star extent]";
1995 else do;
1996 if bit_string_dtype(desc.type) then do;
1997 if mod(sourceL,4) = 0 then do;
1998 if varS then
1999 call ioa_$rsnnl("""^v.4b""b4", out, ioaL, divide(sourceL,4,35,0), bitV);
2000 else call ioa_$rsnnl("""^v.4b""b4", out, ioaL, divide(sourceL,4,35,0), bitS);
2001 end;
2002 else if mod(sourceL,3) = 0 then do;
2003 if varS then
2004 call ioa_$rsnnl("""^v.3b""b3", out, ioaL, divide(sourceL,3,35,0), bitV);
2005 else call ioa_$rsnnl("""^v.3b""b3", out, ioaL, divide(sourceL,3,35,0), bitS);
2006 end;
2007 else do;
2008 if varS then
2009 call ioa_$rsnnl("""^vb""b", out, ioaL, sourceL, bitV);
2010 else call ioa_$rsnnl("""^vb""b", out, ioaL, sourceL, bitS);
2011 end;
2012 end;
2013
2014 else call assign_(addr(out), 2*varying_char_dtype, maxlength(out),
2015 parmP, desc.type*2 + binary(^desc.aligned), sourceL);
2016 end;
2017 go to CONV_return;
2018
2019
2020 CONV (CASEpointer):
2021 dcl my_ptr ptr;
2022 my_ptr = parmToPtrAligned (parmP, desc.aligned);
2023
2024 call ioa_$rsnnl("^p", out, ioaL, my_ptr);
2025 go to CONV_return;
2026
2027
2028 CONV (CASEentry):
2029
2030 dcl my_ent entry variable based(parmP);
2031 call ioa_$rsnnl("^p :: ^p", out, ioaL, codeptr(my_ent), environmentptr(my_ent));
2032 go to CONV_return;
2033
2034
2035 CONV (CASEarea):
2036 call ioa_$rsnnl("area(^d)", out, ioaL, desc.size); NOTE
2037 go to CONV_return;
2038
2039
2040 CONV (0):
2041 call gripe(call_et_$dtype_unsupported, PROC,
2042 "Output parameter type (^d) for: dcl parm^d ^a;", desc.type, i, descriptorString(listDescP) );
2043 return;
2044
2045
2046 CONV_return:
2047
2048 dcl desc_bv bit(36) aligned based(listDescP);
2049 dcl descOut char(200) var;
2050 dcl outP char(20) varying;
2051
2052 if src.ad.given & command then do;
2053 call ioa_$rsnnl("^p -> ", outP, ioaL, parmP);
2054 out = outP || out;
2055 end;
2056 if debugOutput then do; debug
2057 outDump = dump(parmP, desc);
2058 if length(out) + length(outDump) <= MaxLineLen then
2059 out = out || outDump;
2060 else out = out || NL || outDump;
2061 call ioa_$rsnnl("^12.3b type=^a,^36t packed=^[T^;F^], size/prec=^d^[, scale=^d^;^s^]^[, dimensions=^d^;^s^]",
2062 outD, ioaL, desc_bv,
2063 before(pl1_dtype_name(desc.type), "_dtype"), ^desc.aligned, desc.size,
2064 desc.scale ^= 0, desc.scale,
2065 desc.dimensionsCount ^= 0, desc.dimensionsCount);
2066 end;
2067 else if command & src.xtra = XTRAoctal then do; debug
2068 outDump = dump(parmP, desc);
2069 if length(out) + length(outDump) <= MaxLineLen then
2070 out = out || outDump;
2071 else out = out || NL || outDump;
2072 end;
2073 if ^debugOutput & command & targ.case = CASEreturnsStar then do;
2074 call ioa_$rsnnl( debug
2075 xxx
2076
2077
2078 " ^vx desc @ ^p^42t^12.3b type=^a,^36t packed=^[T^;F^], size/prec=^d^[, scale=^d^;^s^]^[, dimensions=^d^;^s^]",
2079 descOut, ioaL, maxlength(s(parmI).id)-length("desc "), listDescP, desc_bv,
2080 before(pl1_dtype_name(desc.type), "_dtype"), ^desc.aligned, desc.size,
2081 desc.scale ^= 0, desc.scale,
2082 desc.dimensionsCount ^= 0, desc.dimensionsCount);
2083 out = out || NL || descOut;
2084 end;
2085 return;
2086
2087
2088 parmToPtrAligned:
2089 proc(P, isAligned) returns(ptr);
2090
2091 dcl P ptr;
2092 dcl isAligned bit(1) aligned;
2093
2094 dcl my_ptr ptr;
2095 dcl parm_ptr ptr based(P);
2096 dcl parm_ptr_packed ptr unaligned based(P);
2097
2098 if isAligned then
2099 return(parm_ptr);
2100 else return(parm_ptr_packed);
2101
2102 end parmToPtrAligned;
2103 %page;
2104
2105
2106
2107
2108
2109
2110 dump:
2111 proc(storeP, d) returns(char(1000) varying);
2112
2113 dcl storeP ptr;
2114 dcl 1 d aligned like target.desc;
2115
2116 dcl wordCount fixed bin(24);
2117 dcl dumpRet char(1000) varying;
2118
2119 dcl ignoreCode fixed bin(35);
2120 dcl maxDumpableWords fixed bin int static options(constant) init(76);
2121 dcl outPrefix char(5) int static options(constant) init(" ");
2122
2123 dcl store (12*wordCount) fixed bin(3) unsigned unaligned based(storeP);
2124
2125 dcl i fixed bin;
2126
2127 call argStorageWords (d.type, d.aligned, d.size, wordCount, ignoreCode);
2128 wordCount = min(wordCount, maxDumpableWords);
2129
2130 dumpRet = outPrefix;
2131 do i = lbound(store,1) to hbound(store,1);
2132 dumpRet = dumpRet || ltrim(char(store(i)));
2133 if mod(i,48) = 0 then dumpRet = dumpRet || NL || outPrefix;
2134
2135 else if mod(i,12) = 0 then dumpRet = dumpRet || " ";
2136
2137 end;
2138 return (dumpRet);
2139 end dump;
2140
2141 end convertOutputArg;
2142 %page;
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156 argSetup:
2157 proc( arg_list, command, af_retP, af_retL, gripe);
2158
2159 dcl arg_list ptr;
2160 dcl command bit(1) aligned;
2161 dcl af_retP ptr;
2162 dcl af_retL fixed bin(21);
2163 dcl gripe entry options(variable) variable;
2164
2165 dcl code fixed bin(35);
2166
2167 dcl active_fnc_err_ entry options (variable);
2168 dcl com_err_ entry () options (variable);
2169 dcl cu_$af_return_arg_rel entry (fixed bin, ptr, fixed bin(21), fixed bin(35), ptr);
2170 dcl cu_$arg_count_rel entry (fixed bin, ptr, fixed bin(35));
2171
2172 argListP = arg_list;
2173
2174 call cu_$af_return_arg_rel (argCount, af_retP, af_retL, code, arg_list);
2175 if code = error_table_$not_act_fnc then do;
2176 command = T;
2177 gripe = com_err_;
2178 call cu_$arg_count_rel (argCount, arg_list, code);
2179 code = 0;
2180 end;
2181 else do;
2182 command = F;
2183 gripe = active_fnc_err_;
2184 end;
2185
2186 if code ^= 0 then do;
2187 call gripe (code, PROC, "When getting argument count and invocation method for ^a.", PROC);
2188 go to EXIT_call;
2189 end;
2190
2191 end argSetup;
2192
2193
2194 dcl argCount fixed bin;
2195 dcl argI fixed bin init (0);
2196 dcl argListP ptr;
2197
2198 dcl argValueCount fixed bin init(0);
2199
2200 argsRemain:
2201 proc () returns (bit (1) aligned);
2202 return (argI < argCount);
2203 end argsRemain;
2204
2205 argValueGetCount:
2206 proc (debug);
2207
2208 dcl debug fixed bin(3) unsigned;
2209
2210 dcl argI_saved fixed bin;
2211 dcl gripe_saved entry variable;
2212 dcl 1 s aligned like source;
2213 dcl 1 o aligned like globalOpt;
2214 dcl code fixed bin(35);
2215
2216 if argsRemain() then do;
2217 argI_saved = argI;
2218 gripe_saved = gripe;
2219 gripe = argValueGetCount;
2220
2221 call argValue (argValueCount+1, s, o, code);
2222 do while (code ^= error_table_$noarg);
2223 argValueCount = argValueCount + 1;
2224 call argValue (1, s, o, code);
2225 end;
2226
2227 argI = argI_saved;
2228 gripe = gripe_saved;
2229
2230 if debug >= 4 then do;
2231 call ioa_ ("argValueCount = ^d", argValueCount);
2232 end;
2233 end;
2234
2235 end argValueGetCount;
2236
2237 %page;
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247 argValue:
2248 proc (n, s, gOpt, code);
2249
2250 dcl n fixed bin;
2251 dcl 1 s aligned like source;
2252 dcl 1 gOpt aligned like globalOpt;
2253 dcl code fixed bin (35);
2254
2255
2256 dcl arg char(argL) based(argP);
2257 dcl argFirst char(1) based(argP);
2258 dcl argL fixed bin(21);
2259 dcl argP ptr;
2260
2261 dcl (argDcl,
2262 argDebug, debug
2263 argID,
2264 argInitVal,
2265 argLen,
2266 argMLen ) bit(1) aligned init(F);
2267
2268 dcl dirValue fixed bin(3);
2269
2270 dcl startedArgValue bit(1) aligned init(F);
2271
2272 code = 0;
2273
2274 dcl cu_$arg_ptr_rel entry (fixed bin, ptr, fixed bin(21), fixed bin(35), ptr);
2275
2276 do while (argsRemain());
2277 call cu_$arg_ptr_rel (argI+1, argP, argL, code, argListP);
2278
2279
2280
2281 if argInitVal then do;
2282 argInitVal = F;
2283 s.argP = argP; s.argL = argL;
2284 end;
2285
2286 else if argDcl then do;
2287 argDcl = F;
2288 if length(arg) > maxlength(s.dcl) & gripe ^= argValueGetCount then do;
2289 call gripe (error_table_$bigarg, PROC,
2290 "Maximum declaration length (^d) exceeded: -addr ^a", maxlength(s.dcl), arg);
2291 go to ERROR_argValue;
2292 end;
2293 s.dcl = arg;
2294 end;
2295
2296 else if argID then do;
2297 argID = F;
2298 call argNotID_Error(arg);
2299 s.id = arg;
2300 end;
2301
2302 else if argLen & argIsID(arg) then do;
2303 argLen = F;
2304 s.L = Lunset;
2305 s.L_id = arg;
2306 end;
2307
2308 else if argLen | argMLen then do;
2309
2310 dcl lengthVar fixed bin(24) aligned based(lengthP);
2311 dcl lengthP ptr;
2312 dcl option char(11) var;
2313
2314 if argLen then do; argLen = F; lengthP = addr(s.L); option = "-length"; s.L_id = ""; end;
2315 else do; argMLen = F; lengthP = addr(s.M); option = "-max_length"; end;
2316
2317 call assign(arg, F, lengthP, FIXED_BIN, ALIGNED, 24, 0, code);
2318 if code ^= 0 & gripe ^= argValueGetCount then do;
2319 call gripe(error_table_$bad_conversion, PROC, "^a ^a", option, arg);
2320 go to ERROR_argValue;
2321 end;
2322 else if lengthVar < 0 & gripe ^= argValueGetCount then do;
2323 call gripe(error_table_$bad_conversion, PROC,
2324 "Option value must be non-negative: ^a ^a", option, arg);
2325 go to ERROR_argValue;
2326 end;
2327 end;
2328
2329 else if argDebug then do; debug
2330 argDebug = F;
2331 call assign(arg, F, addr(gOpt.debug), FIXED_BIN_UNS, ALIGNED, 3, 0, code);
2332 if code ^= 0 & gripe ^= argValueGetCount then do;
2333 call gripe(error_table_$bad_conversion, PROC, "-debug ^a", arg);
2334 go to ERROR_argValue;
2335 end;
2336 else if gOpt.debug > 5 & gripe ^= argValueGetCount then do;
2337 call gripe(error_table_$bad_conversion, PROC, "Option value is an INT in range 0-5: -debug ^a", arg);
2338 go to ERROR_argValue;
2339 end;
2340 end;
2341
2342
2343 else if arg = "-debug" | arg = "-db" then argDebug = T;
2344 else if arg = "-octal" | arg = "-oc" then s.xtra = XTRAoctal;
2345 else if arg = "-all" | arg = "-a" then s.xtra = XTRAall;
2346
2347
2348 else if argValueStarter(arg, dirValue) then do;
2349 if startedArgValue then go to EXIT_argValue;
2350 go to ARG_VALUE_DIR(dirValue);
2351
2352 ARG_VALUE_DIR(DIRunset):
2353 s.argP = argP; s.argL = argL; go to ARG_VALUE_DIR_end;
2354
2355 ARG_VALUE_DIR(DIRin):
2356 ARG_VALUE_DIR(DIRinout):
2357 s.dir = dirValue; argInitVal = T; go to ARG_VALUE_DIR_end;
2358
2359 ARG_VALUE_DIR(DIRout):
2360 ARG_VALUE_DIR(DIRignore):
2361 s.dir = dirValue; go to ARG_VALUE_DIR_end;
2362
2363 ARG_VALUE_DIR_end:
2364 startedArgValue = T;
2365 end;
2366
2367
2368 else if startedArgValue then do;
2369 if argIsFMT (arg, s) then;
2370 else if arg = "-id" then argID = T;
2371 else if arg = "-return" | arg = "-ret" then s.ret = T;
2372 else if arg = "-length" | arg = "-ln" then argLen = T;
2373 else if arg = "-max_length" | arg = "-ml" then argMLen = T;
2374 else if arg = "-declare" | arg = "-dcl" then do; s.meta = METAdcl; argDcl = T; end;
2375 else if arg = "-addr" then do; s.meta = METAaddr; argDcl = T; end;
2376 else call gripe (error_table_$badopt, PROC, "Ignoring unsupported option: ^a", arg);
2377 end;
2378 else call gripe (error_table_$inconsistent, PROC, "Must start an arg_value before using: ^a", arg);
2379
2380 argI = argI + 1;
2381 end;
2382
2383 EXIT_argValue:
2384 code = error_table_$noarg;
2385
2386
2387 if argDebug then
2388 call gripe (code, PROC, "-debug operand is an integer between 0 and 5.");
2389 else if argLen then
2390 call gripe (code, PROC, "-length operand is a non-negative integer or ID of another argument.");
2391 else if argMLen then
2392 call gripe (code, PROC, "-max_length operand is a non-negative integer.");
2393 else if argID then
2394 call gripe (code, PROC, "-id operand is a PL/I identifier.");
2395 else if argDcl then
2396 call gripe (code, PROC, "^a operand is a scalar PL/I declaration.", META.name(s.meta));
2397
2398
2399 else if startedArgValue then
2400 code = 0;
2401
2402
2403 ERROR_argValue:
2404 if gOpt.debug >= 5 then do; Debug
2405
2406 dcl src char(s.argL) based(s.argP);
2407
2408 call ioa_$nnl ("^[
2409 n=0, s.id || ":", n=0, s.dir+1, length(src)>0, src, s.xtra+1);
2410 if n = 0 & gOpt.debug > 0 then
2411 call ioa_$nnl ("-debug ^d ", gOpt.debug);
2412 call ioa_ ("^[^s^;-dcl ""^a"" ^;-addr ""^a"" ^]^[^;-code ^;-date ^;-time ^;-date_time ^]^[-max_length ^d ^;^s^]^[-length ^d ^;^s^]^[-return ^;^]",
2413 s.meta+1, s.dcl, s.fmt+1, s.M>0, s.M, s.L>0, s.L, s.ret);
2414 end;
2415 return;
2416 %page;
2417
2418 argValueStarter:
2419 proc (arg, dirValue) returns (bit(1) aligned);
2420
2421 dcl arg char(*);
2422 dcl dirValue fixed bin(3);
2423
2424 dcl argFirst char(1) defined(arg);
2425
2426 dcl NUMERIC char(17) int static options(constant) init("+-.0123456789efEF");
2427
2428 if length(arg) = 0 then do;
2429 STARTER: dirValue = DIRunset; return(T); end;
2430
2431 if argFirst ^= "-" | arg = NULL_POINTER then go to STARTER;
2432
2433
2434 if verify(arg,NUMERIC) = 0 then go to STARTER;
2435
2436 if oct_or_hex_source(arg, ""b) then go to STARTER;
2437
2438 dirValue = isMember (arg, DIR.tiny);
2439 if dirValue > -1 then return(T);
2440
2441 dirValue = isMember (arg, DIR.abbr);
2442 if dirValue > -1 then return(T);
2443
2444 dirValue = isMember (arg, DIR.name);
2445 if dirValue > -1 then return(T);
2446
2447 return(F);
2448
2449
2450 argIsFMT: entry (arg, s) returns (bit(1) aligned);
2451
2452 dcl 1 s aligned like source;
2453 dcl fmtValue fixed bin(3);
2454
2455 if argFirst ^= "-" then return(F);
2456
2457 fmtValue = isMember (arg, FMT.name);
2458 if fmtValue > FMTunset then do;
2459 FMT_yes: s.fmt = fmtValue;
2460 return(T);
2461 end;
2462
2463 fmtValue = isMember (arg, FMT.abbr);
2464 if fmtValue > FMTunset then go to FMT_yes;
2465 return(F);
2466
2467
2468 argNotID_Error:
2469 entry (arg);
2470
2471 dcl IDENTIFIER char(64) int static options(constant) init("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_$");
2472 dcl IDENTIFIERfirst char(52) int static options(constant) init("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");
2473
2474 if length(arg) < 1 then do;
2475 if gripe ^= argValueGetCount then do;
2476 call gripe (error_table_$smallarg, PROC, "Empty identifier follows: -id");
2477 go to ERROR_argValue;
2478 end;
2479 else return;
2480 end;
2481 if length(arg) > maxlength(s.id) & gripe ^= argValueGetCount then do;
2482 call gripe (error_table_$bigarg, PROC,
2483 "Maximum identifier length (^d) exceeded: -id ^a", maxlength(s.id), arg);
2484 go to ERROR_argValue;
2485 end;
2486 if (verify(argFirst, IDENTIFIERfirst) ^= 0) | (verify(arg, IDENTIFIER) ^= 0) then do;
2487 if gripe ^= argValueGetCount then do;
2488 call gripe (error_table_$badopt, PROC, "-id ^a is not a PL/I identifier.
2489 <identifier> ::= <letter>[<letter>|<digit>|_|$]...", arg);
2490 go to ERROR_argValue;
2491 end;
2492 end;
2493 return;
2494
2495
2496 argIsID: entry (arg) returns (bit(1) aligned);
2497
2498 if length(arg) < 1 then return(F);
2499 if length(arg) > maxlength(s.id) then return(F);
2500 if (verify(argFirst, IDENTIFIERfirst) ^= 0) | (verify(arg, IDENTIFIER) ^= 0) then return(F);
2501 return(T);
2502
2503 end argValueStarter;
2504
2505
2506 isMember: proc (item, array) returns(fixed bin);
2507
2508 dcl item char(*);
2509 dcl array (*) char(*) var;
2510
2511 dcl i fixed bin;
2512 do i = lbound(array,1) to hbound(array,1);
2513 if item = array(i) then return(i);
2514 end;
2515 return(-1);
2516
2517 end isMember;
2518
2519 end argValue;
2520 %page;
2521
2522
2523
2524
2525 descriptorString:
2526 proc (descP) returns (char (100) var);
2527
2528 dcl descP ptr aligned;
2529
2530 dcl desc bit(36) aligned based(descP);
2531
2532 dcl code fixed bin(35);
2533 dcl ret char(2000) var;
2534
2535 dcl get_pl1_parm_desc_string_ entry (ptr, char(*) var, fixed bin(35));
2536
2537 ret = "";
2538 call get_pl1_parm_desc_string_ (descP, ret, code);
2539 if code ^= 0 then
2540 call gripe (code, PROC, "Error converting descriptor to string: ^.3b", desc);
2541 if length(ret) > 100 then
2542 call gripe (code, PROC, "Long descriptor string shortened to 100 chars: ^a", ret);
2543 return (ret);
2544
2545 end descriptorString;
2546
2547 int2digits:
2548 proc (int) returns(char(8) var);
2549
2550 dcl int fixed bin;
2551 dcl digits char(8) var;
2552
2553 if int < 10 then
2554 digits = "0";
2555 else digits = "";
2556 digits = digits || ltrim(char(int));
2557
2558 return (digits);
2559
2560 end int2digits;
2561 %page;
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572 %page;
2573 %include translator_temp_alloc;
2574 %page;
2575 %include area_info;
2576 %page;
2577 %include arg_list;
2578 %page;
2579 %include arg_descriptor;
2580 %page;
2581 %include call_entry_info_;
2582 %page;
2583 %include encoded_precision;
2584 %page;
2585 %include system;
2586 %page;
2587 %include call_dtype_fcns;
2588 end call;