1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 answer:
28 procedure () options (variable);
29
30
31 dcl P_sci_ptr pointer parameter;
32 dcl P_info_ptr pointer parameter;
33
34 dcl sci_ptr pointer;
35
36 dcl 1 answer_node aligned based (answer_node_ptr),
37 2 query_sw bit (1),
38 2 call_sw bit (1),
39 2 call_ptr pointer,
40 2 call_len fixed binary (21),
41 2 times fixed binary,
42 2 next_ptr pointer,
43 2 answer_len fixed binary (21),
44 2 answer character (arg_len refer (answer_node.answer_len));
45 dcl answer_node_ptr pointer;
46
47 dcl 1 match_node aligned based (match_node_ptr),
48 2 exclude_sw bit (1),
49 2 regexp_sw bit (1),
50 2 next_ptr pointer,
51 2 match_len fixed binary (21),
52 2 match_str character (arg_len refer (match_node.match_len)) unaligned;
53 dcl match_node_ptr pointer;
54
55 %include cp_active_string_types;
56
57 dcl arg character (arg_len) based (arg_ptr) unaligned;
58 dcl based_answer character (answer_max_len) based;
59
60 dcl (arg_ptr, first_match_ptr, first_node_ptr, next_node_ptr, old_node_ptr, temp_ptr) pointer;
61
62 dcl area area based (area_ptr);
63 dcl area_ptr pointer;
64
65 dcl (standalone_invocation, brief_sw, call_opt_sw, found_first_answer, is_yes_or_no, yes_no) bit (1) aligned;
66
67 dcl (arg_count, arg_index, n) fixed binary;
68 dcl (answer_max_len, arg_len) fixed binary (21);
69 dcl code fixed binary (35);
70
71 dcl error_table_$bad_conversion fixed binary (35) external;
72 dcl error_table_$badopt fixed binary (35) external;
73 dcl ssu_et_$null_request_line fixed binary (35) external;
74 dcl ssu_et_$subsystem_aborted fixed binary (35) external;
75
76 dcl iox_$user_io pointer external;
77 dcl iox_$user_output pointer external;
78
79 dcl request_sw bit (1) aligned;
80 dcl request_line character (request_len) aligned based (request_ptr);
81 dcl request_ptr pointer;
82 dcl (request_len, request_start, start) fixed binary (21);
83
84 dcl com_err_ entry () options (variable);
85 dcl command_query_ entry () options (variable);
86 dcl condition_ entry (character (*), entry);
87 dcl cu_$arg_list_ptr entry () returns (pointer);
88 dcl cv_dec_check_ entry (character (*), fixed binary (35)) returns (fixed binary (35));
89 dcl get_system_free_area_ entry () returns (pointer);
90 dcl search_file_
91 entry (pointer, fixed binary (21), fixed binary (21), pointer, fixed binary (21), fixed binary (21),
92 fixed binary (21), fixed binary (21), fixed binary (35));
93 dcl ssu_$abort_line entry () options (variable);
94 dcl ssu_$abort_subsystem entry () options (variable);
95 dcl ssu_$arg_count entry (pointer, fixed binary);
96 dcl ssu_$arg_ptr entry (pointer, fixed binary, pointer, fixed binary (21));
97 dcl ssu_$destroy_invocation entry (pointer);
98 dcl ssu_$execute_line entry (pointer, pointer, fixed binary (21), fixed binary (35));
99 dcl ssu_$evaluate_active_string
100 entry (pointer, pointer, character (*), fixed binary, character (*) varying, fixed binary (35));
101 dcl ssu_$get_subsystem_and_request_name entry (pointer) returns (character (72) varying);
102 dcl ssu_$get_request_name entry (pointer) returns (character (32));
103 dcl ssu_$get_temp_segment entry (pointer, character (*), pointer);
104 dcl ssu_$print_message entry () options (variable);
105 dcl ssu_$release_temp_segment entry (pointer, pointer);
106 dcl ssu_$standalone_invocation entry (pointer, character (*), character (*), pointer, entry, fixed binary (35));
107
108 dcl (addr, binary, index, min, null, substr) builtin;
109
110 dcl (cleanup, command_question) condition;
111 %page;
112 %include query_info_;
113 %page;
114 %include condition_info_header;
115 %include command_question_info;
116 %page;
117
118
119
120
121
122 standalone_invocation = "1"b;
123 call ssu_$standalone_invocation (sci_ptr, "answer", "1.0", cu_$arg_list_ptr (), abort_answer_command, code);
124 if code ^= 0 then do;
125 call com_err_ (code, "answer", "Can not establish standalone subsystem invocation.");
126 return;
127 end;
128 go to COMMON;
129
130
131
132
133 ssu_answer_request_:
134 entry (P_sci_ptr, P_info_ptr);
135
136 standalone_invocation = "0"b;
137 sci_ptr = P_sci_ptr;
138 go to COMMON;
139
140
141
142
143 COMMON:
144 area_ptr = get_system_free_area_ ();
145 answer_node_ptr, match_node_ptr, request_ptr, first_match_ptr, first_node_ptr, temp_ptr = null ();
146
147 on condition (cleanup) call clean_up ();
148
149 call ssu_$arg_count (sci_ptr, arg_count);
150 if arg_count = 0 then
151 USAGE:
152 call ssu_$abort_line (sci_ptr, 0, "Usage: ^a string {-control_args} ^[command^;request^] line",
153 ssu_$get_request_name (sci_ptr), standalone_invocation);
154
155
156 call ssu_$arg_ptr (sci_ptr, 1, arg_ptr, arg_len);
157
158 call add_answer_node ();
159 first_node_ptr = answer_node_ptr;
160
161 brief_sw, call_opt_sw = "0"b;
162 found_first_answer = ""b;
163 request_sw = "0"b;
164 request_start = 0;
165 request_len = 0;
166
167 do arg_index = 1 to arg_count;
168 call ssu_$arg_ptr (sci_ptr, arg_index, arg_ptr, arg_len);
169 if ^request_sw then
170 if substr (arg, 1, 1) = "-" then
171 if arg = "-brief" | arg = "-bf" then brief_sw = "1"b;
172
173 else if arg = "-times" then do;
174 if ^found_first_answer then
175 no_first:
176 call ssu_$abort_line (sci_ptr, 0, "First answer missing before ""^a"".", arg);
177 arg_index = arg_index + 1;
178 if arg_index > arg_count then
179 NO_CONTROL_VALUE:
180 call ssu_$abort_line (sci_ptr, 0, "No value specified for ""^a"".", arg);
181 call ssu_$arg_ptr (sci_ptr, arg_index, arg_ptr, arg_len);
182 n = cv_dec_check_ (arg, code);
183 if code ^= 0 then
184 call ssu_$abort_line (sci_ptr, error_table_$bad_conversion, "-times ""^a""", arg);
185 answer_node.times = n;
186 end;
187 else if arg = "-call" then do;
188 call_opt_sw = "1"b;
189 arg_index = arg_index + 1;
190 if arg_index > arg_count then go to NO_CONTROL_VALUE;
191 call ssu_$arg_ptr (sci_ptr, arg_index, arg_ptr, arg_len);
192 if found_first_answer then
193 call add_answer_node ();
194 else found_first_answer = "1"b;
195 answer_node.call_sw = "1"b;
196 answer_node.call_ptr = arg_ptr;
197 answer_node.call_len = arg_len;
198 end;
199 else if arg = "-exclude" | arg = "-ex" then do;
200 arg_index = arg_index + 1;
201 if arg_index > arg_count then go to NO_CONTROL_VALUE;
202 call ssu_$arg_ptr (sci_ptr, arg_index, arg_ptr, arg_len);
203 call add_match_node ();
204 match_node.exclude_sw = "1"b;
205 MATCH_ARG:
206 if substr (arg, 1, 1) = "/" & substr (arg, arg_len, 1) = "/" then do;
207 match_node.regexp_sw = "1"b;
208 match_node.match_len = arg_len - 2;
209 match_node.match_str = substr (arg, 2, arg_len - 2);
210 end;
211 else do;
212 match_node.regexp_sw = "0"b;
213 match_node.match_str = arg;
214 end;
215 end;
216 else if arg = "-match" then do;
217 arg_index = arg_index + 1;
218 if arg_index > arg_count then go to NO_CONTROL_VALUE;
219 call ssu_$arg_ptr (sci_ptr, arg_index, arg_ptr, arg_len);
220 call add_match_node ();
221 match_node.exclude_sw = "0"b;
222 go to MATCH_ARG;
223 end;
224 else if arg = "-query" then do;
225 if found_first_answer then
226 call add_answer_node ();
227 answer_node.query_sw = "1"b;
228 found_first_answer = "1"b;
229 end;
230 else if arg = "-then" then do;
231 if ^found_first_answer then go to no_first;
232 arg_index = arg_index + 1;
233 if arg_index > arg_count then go to NO_CONTROL_VALUE;
234 call ssu_$arg_ptr (sci_ptr, arg_index, arg_ptr, arg_len);
235 call add_answer_node ();
236 answer_node.answer = arg;
237 end;
238 else call ssu_$abort_line (sci_ptr, error_table_$badopt, """^a""", arg);
239 else do;
240 if ^found_first_answer then do;
241 answer_node.answer = arg;
242 found_first_answer = "1"b;
243 end;
244 else do;
245 request_sw = "1"b;
246 request_start = arg_index;
247 request_len = arg_len + 1;
248 end;
249 end;
250
251 else request_len = request_len + arg_len + 1;
252 end;
253
254 if request_len = 0 then go to USAGE;
255 answer_node_ptr = first_node_ptr;
256
257 if call_opt_sw then call ssu_$get_temp_segment (sci_ptr, "answer", temp_ptr);
258
259 call condition_ ("command_question", answer_handler);
260
261
262 allocate request_line in (area) set (request_ptr);
263 request_line = "";
264
265 start = 1;
266 do arg_index = request_start to arg_count;
267 call ssu_$arg_ptr (sci_ptr, arg_index, arg_ptr, arg_len);
268 substr (request_line, start, arg_len) = arg;
269 start = start + arg_len + 1;
270 end;
271
272 call ssu_$execute_line (sci_ptr, addr (request_line), start - 2, code);
273
274 if ^standalone_invocation & (code ^= 0) & (code ^= ssu_et_$null_request_line) then
275 if code = ssu_et_$subsystem_aborted then
276 call ssu_$abort_subsystem (sci_ptr);
277 else call ssu_$abort_line (sci_ptr);
278
279 RETURN:
280 call clean_up ();
281
282 return;
283
284
285
286
287
288 abort_answer_command:
289 procedure ();
290
291 go to RETURN;
292
293 end abort_answer_command;
294
295 %page;
296
297
298
299
300 answer_handler:
301 procedure (mcptr, name, coptr, infoptr, continue_sw);
302
303 dcl (mcptr, coptr, infoptr) pointer parameter;
304 dcl name character (*) parameter;
305 dcl continue_sw bit (1) aligned parameter;
306
307 %include query_info;
308
309 dcl 1 as aligned based (inp),
310 2 version fixed binary,
311 2 status_code fixed binary (35),
312 2 query_code fixed binary,
313 2 question_sw bit (1) unaligned,
314 2 yes_or_no_sw bit (1) unaligned,
315 2 preset_sw bit (1) unaligned,
316 2 answer_sw bit (1) unaligned,
317 2 np pointer,
318 2 nl fixed binary,
319 2 question_ptr pointer,
320 2 question_len fixed binary (21),
321 2 max_question_len fixed binary (21),
322 2 answer_ptr pointer,
323 2 answer_len fixed binary (21),
324 2 max_answer_len fixed binary (21);
325
326 declare 1 cqi aligned based (inp) like command_question_info;
327
328 dcl inp pointer;
329
330 dcl temp_answer character (4 * sys_info$max_seg_size - 4) varying based (temp_ptr);
331 dcl sys_info$max_seg_size fixed binary (35) external;
332 dcl question_string character (question_len) based (question_ptr);
333 dcl buffer character (buffer_len) based (buffer_ptr);
334 dcl (buffer_ptr, question_ptr) pointer;
335 dcl buffer_len fixed binary (21);
336 dcl question_len fixed binary (21);
337 dcl length builtin;
338
339 inp = infoptr;
340
341 if as.version = 2 then do;
342 question_ptr = as.question_ptr;
343 question_len = as.question_len;
344 end;
345 else do;
346 question_ptr = cqi.question_ptr;
347 question_len = cqi.question_lth;
348 end;
349
350 if first_match_ptr ^= null () then do;
351 call process_selections (continue_sw, question_ptr, question_len);
352 if continue_sw then return;
353 end;
354
355 if answer_node_ptr = null ()
356 | (as.version ^= 2 & cqi.version < 3)
357 then do;
358 continue_sw = "1"b;
359 return;
360 end;
361
362 if answer_node.call_sw then do;
363 buffer_ptr = answer_node.call_ptr;
364 buffer_len = answer_node.call_len;
365 on command_question system;
366 call ssu_$evaluate_active_string (sci_ptr, null (), buffer, NORMAL_ACTIVE_STRING, temp_answer, code);
367 if code ^= 0 then do;
368 call ssu_$print_message (sci_ptr, code, "[^a]", buffer);
369 query_info.suppress_name_sw = "1"b;
370 if as.version = 2 then
371 query_info.yes_or_no_sw = as.yes_or_no_sw;
372 else query_info.yes_or_no_sw = cqi.yes_or_no_sw;
373
374 call command_query_ (addr (query_info), temp_answer, ssu_$get_subsystem_and_request_name (sci_ptr),
375 "Please type answer to the following question:^/^a", question_string);
376 end;
377 revert command_question;
378 if as.version = 2 then
379 yes_no = as.yes_or_no_sw;
380 else yes_no = cqi.yes_or_no_sw;
381 if temp_answer = "true" then temp_answer = "yes";
382 else if temp_answer = "false" then temp_answer = "no";
383 if temp_answer = "yes" | temp_answer = "y" | temp_answer = "no" | temp_answer = "n" then
384 is_yes_or_no = "1"b;
385 else is_yes_or_no = "0"b;
386 answer_node.answer_len = length (temp_answer);
387 go to SET_ANSWER;
388 end;
389
390 else if answer_node.query_sw then do;
391 if cqi.version >= 4 then do;
392 cqi.question_iocbp = iox_$user_io;
393 cqi.answer_iocbp = iox_$user_io;
394 end;
395 continue_sw = "1"b;
396 end;
397
398 else do;
399 if answer_node.answer = "yes" | answer_node.answer = "y" | answer_node.answer = "no"
400 | answer_node.answer = "n" then
401 is_yes_or_no = "1"b;
402 else is_yes_or_no = "0"b;
403 SET_ANSWER:
404 if as.version = 2 then do;
405 if as.yes_or_no_sw & ^is_yes_or_no then do;
406 REJECT_NON_YES_NO:
407 if answer_node.call_sw then
408 call ssu_$print_message (sci_ptr, 0,
409 "Ignoring response ""^a"" to yes-or-no question:^/^a",
410 temp_answer, question_string);
411 else call ssu_$print_message (sci_ptr, 0,
412 "Ignoring response ""^a"" to yes-or-no question:^/^a",
413 answer_node.answer, question_string);
414 continue_sw = "1"b;
415 return;
416 end;
417 answer_max_len = as.max_answer_len;
418 as.answer_len = min (answer_max_len, answer_node.answer_len);
419
420 if answer_node.call_sw then
421 substr (as.answer_ptr -> based_answer, 1, as.answer_len) = temp_answer;
422 else substr (as.answer_ptr -> based_answer, 1, as.answer_len) = answer_node.answer;
423 as.preset_sw = "1"b;
424 as.question_sw, as.answer_sw = ^brief_sw;
425 end;
426
427 else if cqi.version >= 3 then do;
428 if cqi.yes_or_no_sw & ^is_yes_or_no then go to REJECT_NON_YES_NO;
429 answer_max_len = cqi.max_answer_lth;
430 cqi.answer_lth = min (answer_node.answer_len, answer_max_len);
431
432 if answer_node.call_sw then
433 substr (cqi.answer_ptr -> based_answer, 1, cqi.answer_lth) = temp_answer;
434 else substr (cqi.answer_ptr -> based_answer, 1, cqi.answer_lth) = answer_node.answer;
435 cqi.preset_sw = "1"b;
436 cqi.question_sw, cqi.answer_sw = ^brief_sw;
437 if cqi.version > 3 then
438 cqi.question_iocbp = iox_$user_output;
439 end;
440
441 else do;
442 continue_sw = "1"b;
443 return;
444 end;
445 end;
446
447 answer_node.times = answer_node.times - 1;
448 if answer_node.times = 0 then answer_node_ptr = answer_node.next_ptr;
449
450 return;
451
452 end answer_handler;
453 %page;
454 add_answer_node:
455 procedure ();
456
457 old_node_ptr = answer_node_ptr;
458
459 allocate answer_node in (area) set (answer_node_ptr);
460
461 answer_node.next_ptr = null ();
462
463 if old_node_ptr ^= null () then do;
464 old_node_ptr -> answer_node.next_ptr = answer_node_ptr;
465 if old_node_ptr -> answer_node.times = -1 then old_node_ptr -> answer_node.times = 1;
466
467 end;
468
469 answer_node.query_sw = "0"b;
470 answer_node.call_sw = "0"b;
471 answer_node.times = -1;
472
473 end add_answer_node;
474
475
476
477 add_match_node:
478 procedure ();
479
480 old_node_ptr = match_node_ptr;
481
482 allocate match_node in (area) set (match_node_ptr);
483
484 match_node.next_ptr = null ();
485
486 if old_node_ptr ^= null () then
487 old_node_ptr -> match_node.next_ptr = match_node_ptr;
488
489 if first_match_ptr = null () then first_match_ptr = match_node_ptr;
490
491 end add_match_node;
492
493
494 clean_up:
495 procedure ();
496
497 if request_ptr ^= null () then free request_line in (area);
498
499 if temp_ptr ^= null () then call ssu_$release_temp_segment (sci_ptr, temp_ptr);
500
501 do answer_node_ptr = first_node_ptr repeat next_node_ptr while (answer_node_ptr ^= null ());
502 next_node_ptr = answer_node.next_ptr;
503 free answer_node in (area);
504 end;
505
506 do match_node_ptr = first_match_ptr repeat next_node_ptr while (match_node_ptr ^= null ());
507 next_node_ptr = match_node.next_ptr;
508 free match_node in (area);
509 end;
510
511 if standalone_invocation then
512 call ssu_$destroy_invocation (sci_ptr);
513
514 end clean_up;
515 %page;
516 process_selections:
517 procedure (P_continue_sw, P_question_ptr, P_question_len);
518
519 dcl P_continue_sw bit (1) aligned;
520 dcl P_question_ptr pointer;
521 dcl P_question_len fixed binary (21);
522 dcl (match_node_ptr, mp) pointer;
523
524 match_node_ptr = first_match_ptr;
525
526 if match_node_ptr -> match_node.exclude_sw then
527 P_continue_sw = "0"b;
528 else P_continue_sw = "1"b;
529
530 do mp = match_node_ptr repeat (mp -> match_node.next_ptr) while (mp ^= null ());
531 if mp -> match_node.exclude_sw then do;
532 if ^P_continue_sw then
533 if match_one (mp, P_question_ptr, P_question_len) then P_continue_sw = "1"b;
534 end;
535 else if P_continue_sw then
536 if match_one (mp, P_question_ptr, P_question_len) then P_continue_sw = "0"b;
537 end;
538
539 return;
540
541
542
543
544 match_one:
545 procedure (P_mp, P_ptr, P_len) returns (bit (1));
546
547 dcl P_mp pointer;
548 dcl P_ptr pointer;
549 dcl P_len fixed binary (21);
550 dcl question_string character (P_len) based (P_ptr);
551
552 if P_mp -> match_node.regexp_sw then
553 call search_file_ (addr (P_mp -> match_node.match_str), 1, P_mp -> match_node.match_len, P_ptr, 1,
554 P_len, 0, 0, code);
555
556 else code = binary ((index (question_string, P_mp -> match_node.match_str) = 0), 35, 0);
557
558
559 return (code = 0);
560
561 end match_one;
562
563 end process_selections;
564
565 end answer;