1 package org.sentrysoftware.jawk.jrt;
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
28
29
30
31 import java.io.FileOutputStream;
32 import java.io.FileReader;
33 import java.io.IOException;
34 import java.io.InputStream;
35 import java.io.InputStreamReader;
36 import java.io.PrintStream;
37 import java.util.ArrayList;
38 import java.util.Date;
39 import java.util.Enumeration;
40 import java.util.HashMap;
41 import java.util.HashSet;
42 import java.util.IllegalFormatException;
43 import java.util.List;
44 import java.util.Locale;
45 import java.util.Map;
46 import java.util.Random;
47 import java.util.Set;
48 import java.util.StringTokenizer;
49 import java.util.regex.Matcher;
50 import java.util.regex.Pattern;
51
52 import org.sentrysoftware.jawk.intermediate.UninitializedObject;
53 import org.sentrysoftware.jawk.util.AwkLogger;
54 import org.slf4j.Logger;
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92 public class JRT {
93
94 private static final Logger LOG = AwkLogger.getLogger(JRT.class);
95
96 private static final boolean IS_WINDOWS = (System.getProperty("os.name").indexOf("Windows") >= 0);
97
98 private VariableManager vm;
99
100 private Map<String, Process> output_processes = new HashMap<String, Process>();
101 private Map<String, PrintStream> output_streams = new HashMap<String, PrintStream>();
102
103
104 private PartitioningReader partitioningReader = null;
105
106 private String inputLine = null;
107
108 private List<String> input_fields = new ArrayList<String>(100);
109 private AssocArray arglist_aa = null;
110 private int arglist_idx;
111 private boolean has_filenames = false;
112 private static final UninitializedObject BLANK = new UninitializedObject();
113
114 private static final Integer ONE = Integer.valueOf(1);
115 private static final Integer ZERO = Integer.valueOf(0);
116 private static final Integer MINUS_ONE = Integer.valueOf(-1);
117 private String jrt_input_string;
118
119 private Map<String, PartitioningReader> file_readers = new HashMap<String, PartitioningReader>();
120 private Map<String, PartitioningReader> command_readers = new HashMap<String, PartitioningReader>();
121 private Map<String, Process> command_processes = new HashMap<String, Process>();
122 private Map<String, PrintStream> outputFiles = new HashMap<String, PrintStream>();
123
124
125
126
127
128
129 public JRT(VariableManager vm) {
130 this.vm = vm;
131 }
132
133
134
135
136
137
138
139 public final void assignInitialVariables(Map<String, Object> initial_var_map) {
140 assert initial_var_map != null;
141 for (Map.Entry<String, Object> var : initial_var_map.entrySet()) {
142 vm.assignVariable(var.getKey(), var.getValue());
143 }
144 }
145
146
147
148
149
150
151
152
153
154
155 public static void assignEnvironmentVariables(AssocArray aa) {
156 assert aa.keySet().isEmpty();
157 Map<String, String> env = System.getenv();
158 for (Map.Entry<String, String> var : env.entrySet()) {
159 aa.put(var.getKey(), var.getValue());
160 }
161 }
162
163
164
165
166
167
168
169
170
171
172 public static String toAwkString(Object o, String convfmt, Locale locale) {
173
174 if (o instanceof Number) {
175
176 double d = ((Number) o).doubleValue();
177 if (d == (long) d) {
178
179 return Long.toString((long) d);
180 } else {
181
182 try {
183 String s = String.format(locale, convfmt, d);
184
185
186
187 if ((s.indexOf('.') > -1 || s.indexOf(',') > -1) && (s.indexOf('e') + s.indexOf('E') == -2)) {
188 while (s.endsWith("0")) {
189 s = s.substring(0, s.length() - 1);
190 }
191 if (s.endsWith(".") || s.endsWith(",")) {
192 s = s.substring(0, s.length() - 1);
193 }
194 }
195 return s;
196 } catch (java.util.UnknownFormatConversionException ufce) {
197
198 return "";
199 }
200 }
201 } else {
202
203 return o.toString();
204 }
205 }
206
207
208
209
210
211
212
213
214
215
216
217
218 public static String toAwkStringForOutput(Object o, String ofmt, Locale locale) {
219
220
221
222
223 if (!(o instanceof Number)) {
224 try {
225 o = Double.parseDouble(o.toString());
226 } catch (NumberFormatException e) {
227
228 }
229 }
230
231 return toAwkString(o, ofmt, locale);
232 }
233
234
235
236
237
238
239
240
241 public static double toDouble(final Object o) {
242
243 if (o == null) {
244 return 0;
245 }
246
247 if (o instanceof Number) {
248 return ((Number) o).doubleValue();
249 }
250
251 if (o instanceof Character) {
252 return (double)((Character)o).charValue();
253 }
254
255
256 String s = o.toString();
257 int length = s.length();
258
259
260
261 if (length > 26) {
262 length = 26;
263 }
264
265
266
267
268 while (length > 0) {
269 try {
270 return Double.parseDouble(s.substring(0, length));
271 } catch (NumberFormatException nfe) {
272 length--;
273 }
274 }
275
276
277 return 0;
278 }
279
280
281
282
283
284
285
286
287 public static long toLong(final Object o) {
288
289 if (o == null) {
290 return 0;
291 }
292
293 if (o instanceof Number) {
294 return ((Number)o).longValue();
295 }
296
297 if (o instanceof Character) {
298 return (long)((Character)o).charValue();
299 }
300
301
302 String s = o.toString();
303 int length = s.length();
304
305
306
307 if (length > 20) {
308 length = 20;
309 }
310
311
312
313
314 while (length > 0) {
315 try {
316 return Long.parseLong(s.substring(0, length));
317 } catch (NumberFormatException nfe) {
318 length--;
319 }
320
321 }
322
323 return 0;
324 }
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340 public static boolean compare2(Object o1, Object o2, int mode) {
341
342
343 String o1String = o1.toString();
344 String o2String = o2.toString();
345
346
347 if (o1 instanceof UninitializedObject) {
348 if (o2 instanceof UninitializedObject ||
349 "".equals(o2String) ||
350 "0".equals(o2String)) {
351 return mode == 0;
352 } else {
353 return mode < 0;
354 }
355 }
356 if (o2 instanceof UninitializedObject) {
357 if ("".equals(o1String) ||
358 "0".equals(o1String)) {
359 return mode == 0;
360 } else {
361 return mode > 0;
362 }
363 }
364
365 if (!(o1 instanceof Number) && !o1String.isEmpty()) {
366 char o1FirstChar = o1String.charAt(0);
367 if (o1FirstChar >= '0' && o1FirstChar <= '9') {
368 try {
369 o1 = Double.parseDouble(o1String);
370 } catch (NumberFormatException nfe) { }
371 }
372 }
373 if (!(o2 instanceof Number) && !o2String.isEmpty()) {
374 char o2FirstChar = o2String.charAt(0);
375 if (o2FirstChar >= '0' && o2FirstChar <= '9') {
376 try {
377 o2 = Double.parseDouble(o2String);
378 } catch (NumberFormatException nfe) { }
379 }
380 }
381
382 if ((o1 instanceof Number) && (o2 instanceof Number)) {
383 if (mode < 0) {
384 return (((Number) o1).doubleValue() < ((Number) o2).doubleValue());
385 } else if (mode == 0) {
386 return (((Number) o1).doubleValue() == ((Number) o2).doubleValue());
387 } else {
388 return (((Number) o1).doubleValue() > ((Number) o2).doubleValue());
389 }
390 } else {
391
392
393 if (mode == 0) {
394 return o1String.equals(o2String);
395 } else if (mode < 0) {
396 return o1String.compareTo(o2String) < 0;
397 } else {
398 return o1String.compareTo(o2String) > 0;
399 }
400 }
401 }
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417 public static Object inc(Object o) {
418 assert (o != null);
419 double ans;
420 if (o instanceof Number) {
421 ans = ((Number) o).doubleValue() + 1;
422 } else {
423 try {
424 ans = Double.parseDouble(o.toString()) + 1;
425 } catch (NumberFormatException nfe) {
426 ans = 1;
427 }
428 }
429 if (ans == (long) ans) {
430 return (long) ans;
431 } else {
432 return ans;
433 }
434 }
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450 public static Object dec(Object o) {
451 double ans;
452 if (o instanceof Number) {
453 ans = ((Number) o).doubleValue() - 1;
454 } else {
455 try {
456 ans = Double.parseDouble(o.toString()) - 1;
457 } catch (NumberFormatException nfe) {
458 ans = 1;
459 }
460 }
461 if (ans == (long) ans) {
462 return (long) ans;
463 } else {
464 return ans;
465 }
466 }
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485 public final boolean toBoolean(Object o) {
486 boolean val;
487 if (o instanceof Integer) {
488 val = ((Integer)o).intValue() != 0;
489 } else if (o instanceof Long) {
490 val = ((Long)o).longValue() != 0;
491 } else if (o instanceof Double) {
492 val = ((Double)o).doubleValue() != 0;
493 } else if (o instanceof String) {
494 val = (o.toString().length() > 0);
495 } else if (o instanceof UninitializedObject) {
496 val = false;
497 } else if (o instanceof Pattern) {
498
499
500 Pattern pattern = (Pattern) o;
501 String s = inputLine == null ? "" : inputLine;
502 Matcher matcher = pattern.matcher(s);
503 val = matcher.find();
504 } else {
505 throw new Error("Unknown operand_stack type: " + o.getClass() + " for value " + o);
506 }
507 return val;
508 }
509
510
511
512
513
514
515
516
517
518
519
520
521 public static int split(Object array, Object string, String convfmt, Locale locale) {
522 return splitWorker(new StringTokenizer(toAwkString(string, convfmt, locale)), (AssocArray) array);
523 }
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538 public static int split(Object fs, Object array, Object string, String convfmt, Locale locale) {
539 String fs_string = toAwkString(fs, convfmt, locale);
540 if (fs_string.equals(" ")) {
541 return splitWorker(new StringTokenizer(toAwkString(string, convfmt, locale)), (AssocArray) array);
542 } else if (fs_string.equals("")) {
543 return splitWorker(new CharacterTokenizer(toAwkString(string, convfmt, locale)), (AssocArray) array);
544 } else if (fs_string.length() == 1) {
545 return splitWorker(new SingleCharacterTokenizer(toAwkString(string, convfmt, locale), fs_string.charAt(0)), (AssocArray) array);
546 } else {
547 return splitWorker(new RegexTokenizer(toAwkString(string, convfmt, locale), fs_string), (AssocArray) array);
548 }
549 }
550
551 private static int splitWorker(Enumeration<Object> e, AssocArray aa) {
552 int cnt = 0;
553 aa.clear();
554 while (e.hasMoreElements()) {
555 aa.put(++cnt, e.nextElement());
556 }
557 return cnt;
558 }
559
560
561
562
563
564
565 public PartitioningReader getPartitioningReader() {
566 return partitioningReader;
567 }
568
569
570
571
572
573
574 public String getInputLine() {
575 return inputLine;
576 }
577
578
579
580
581
582
583 public void setInputLine(String inputLine) {
584 this.inputLine = inputLine;
585 }
586
587
588
589
590
591
592
593
594
595
596
597
598 public boolean jrtConsumeInput(final InputStream input, boolean for_getline, Locale locale) throws IOException {
599
600 if (arglist_aa == null) {
601 Object arglist_obj = vm.getARGV();
602 arglist_aa = (AssocArray) arglist_obj;
603 arglist_idx = 1;
604
605
606
607 int argc = (int) toDouble(vm.getARGC());
608
609
610
611
612
613
614
615
616
617 for (long i = 1; i < argc; i++) {
618 if (arglist_aa.isIn(i)) {
619 Object namevalue_or_filename_object = arglist_aa.get(i);
620 String namevalue_or_filename = toAwkString(namevalue_or_filename_object, vm.getCONVFMT().toString(), locale);
621 if (namevalue_or_filename.indexOf('=') == -1) {
622
623 has_filenames = true;
624 break;
625 }
626 }
627 }
628 }
629
630
631
632
633 while (true) {
634 try {
635 if (partitioningReader == null) {
636 int argc = (int) toDouble(vm.getARGC());
637 Object o = BLANK;
638 while(arglist_idx <= argc) {
639 o = arglist_aa.get(arglist_idx);
640 ++arglist_idx;
641 if (!(o instanceof UninitializedObject || o.toString().isEmpty())) {
642 break;
643 }
644 }
645 if (!(o instanceof UninitializedObject || o.toString().isEmpty())) {
646 String name_value_or_filename = toAwkString(o, vm.getCONVFMT().toString(), locale);
647 if (name_value_or_filename.indexOf('=') == -1) {
648 partitioningReader = new PartitioningReader(new FileReader(name_value_or_filename), vm.getRS().toString(), true);
649 vm.setFILENAME(name_value_or_filename);
650 vm.resetFNR();
651 } else {
652 setFilelistVariable(name_value_or_filename);
653 if (!has_filenames) {
654
655 partitioningReader = new PartitioningReader(new InputStreamReader(input), vm.getRS().toString());
656 vm.setFILENAME("");
657 } else {
658 continue;
659 }
660 }
661 } else if (!has_filenames) {
662 partitioningReader = new PartitioningReader(new InputStreamReader(input), vm.getRS().toString());
663 vm.setFILENAME("");
664 } else {
665 return false;
666 }
667 } else if (inputLine == null) {
668 if (has_filenames) {
669 int argc = (int) toDouble(vm.getARGC());
670 Object o = BLANK;
671 while(arglist_idx <= argc) {
672 o = arglist_aa.get(arglist_idx);
673 ++arglist_idx;
674 if (!(o instanceof UninitializedObject || o.toString().isEmpty())) {
675 break;
676 }
677 }
678 if (!(o instanceof UninitializedObject || o.toString().isEmpty())) {
679 String name_value_or_filename = toAwkString(o, vm.getCONVFMT().toString(), locale);
680 if (name_value_or_filename.indexOf('=') == -1) {
681
682 partitioningReader = new PartitioningReader(new FileReader(name_value_or_filename), vm.getRS().toString(), true);
683 vm.setFILENAME(name_value_or_filename);
684 vm.resetFNR();
685 } else {
686 setFilelistVariable(name_value_or_filename);
687 vm.incNR();
688 continue;
689 }
690 } else {
691 return false;
692 }
693 } else {
694 return false;
695 }
696 }
697
698
699
700
701
702
703
704
705 inputLine = partitioningReader.readRecord();
706 if (inputLine == null) {
707 continue;
708 } else {
709 if (for_getline) {
710
711
712
713 } else {
714
715
716 jrtParseFields();
717 }
718 vm.incNR();
719 if (partitioningReader.fromFilenameList()) {
720 vm.incFNR();
721 }
722 return true;
723 }
724 } catch (IOException ioe) {
725 LOG.warn("IO Exception", ioe);
726 continue;
727 }
728 }
729 }
730
731 private void setFilelistVariable(String name_value) {
732 int eq_idx = name_value.indexOf('=');
733
734 assert eq_idx >= 0;
735 if (eq_idx == 0) {
736 throw new IllegalArgumentException("Must have a non-blank variable name in a name=value variable assignment argument.");
737 }
738 String name = name_value.substring(0, eq_idx);
739 String value = name_value.substring(eq_idx + 1);
740 Object obj;
741 try {
742 obj = Integer.parseInt(value);
743 } catch (NumberFormatException nfe) {
744 try {
745 obj = Double.parseDouble(value);
746 } catch (NumberFormatException nfe2) {
747 obj = value;
748 }
749 }
750 vm.assignVariable(name, obj);
751 }
752
753
754
755
756
757 public void jrtParseFields() {
758 String fs_string = vm.getFS().toString();
759 Enumeration<Object> tokenizer;
760 if (fs_string.equals(" ")) {
761 tokenizer = new StringTokenizer(inputLine);
762 } else if (fs_string.length() == 1) {
763 tokenizer = new SingleCharacterTokenizer(inputLine, fs_string.charAt(0));
764 } else if (fs_string.equals("")) {
765 tokenizer = new CharacterTokenizer(inputLine);
766 } else {
767 tokenizer = new RegexTokenizer(inputLine, fs_string);
768 }
769
770 assert inputLine != null;
771 input_fields.clear();
772 input_fields.add(inputLine);
773 while (tokenizer.hasMoreElements()) {
774 input_fields.add((String) tokenizer.nextElement());
775 }
776
777 recalculateNF();
778 }
779
780 private void recalculateNF() {
781 vm.setNF(Integer.valueOf(input_fields.size() - 1));
782 }
783
784 private static int toFieldNumber(Object o) {
785 int fieldnum;
786 if (o instanceof Number) {
787 fieldnum = ((Number) o).intValue();
788 } else {
789 try {
790 fieldnum = (int) Double.parseDouble(o.toString());
791 } catch (NumberFormatException nfe) {
792 throw new RuntimeException("Field $(" + o.toString() + ") is incorrect.");
793 }
794 }
795 return fieldnum;
796 }
797
798
799
800
801
802
803
804 public Object jrtGetInputField(Object fieldnum_obj) {
805 return jrtGetInputField(toFieldNumber(fieldnum_obj));
806 }
807
808
809
810
811
812
813
814 public Object jrtGetInputField(int fieldnum) {
815 if (fieldnum < input_fields.size()) {
816 String retval = input_fields.get(fieldnum);
817 assert retval != null;
818 return retval;
819 } else {
820 return BLANK;
821 }
822 }
823
824
825
826
827
828
829
830
831 public String jrtSetInputField(Object value_obj, int field_num) {
832 assert field_num >= 1;
833 assert value_obj != null;
834 String value = value_obj.toString();
835
836 if (value_obj instanceof UninitializedObject) {
837 if (field_num < input_fields.size()) {
838 input_fields.set(field_num, "");
839 }
840 } else {
841
842 for (int i = input_fields.size() - 1; i < field_num; i++) {
843 input_fields.add("");
844 }
845 input_fields.set(field_num, value);
846 }
847
848 rebuildDollarZeroFromFields();
849
850 recalculateNF();
851 return value;
852 }
853
854 private void rebuildDollarZeroFromFields() {
855 StringBuilder new_dollar_zero_sb = new StringBuilder();
856 String ofs = vm.getOFS().toString();
857 for (int i = 1; i < input_fields.size(); i++) {
858 if (i > 1) {
859 new_dollar_zero_sb.append(ofs);
860 }
861 new_dollar_zero_sb.append(input_fields.get(i));
862 }
863 input_fields.set(0, new_dollar_zero_sb.toString());
864 }
865
866
867
868
869
870
871
872 public Integer jrtConsumeFileInputForGetline(String filename) {
873 try {
874 if (jrtConsumeFileInput(filename)) {
875 return ONE;
876 } else {
877 jrt_input_string = "";
878 return ZERO;
879 }
880 } catch (IOException ioe) {
881 jrt_input_string = "";
882 return MINUS_ONE;
883 }
884 }
885
886
887
888
889
890
891
892
893
894 public Integer jrtConsumeCommandInputForGetline(String cmd_string) {
895 try {
896 if (jrtConsumeCommandInput(cmd_string)) {
897 return ONE;
898 } else {
899 jrt_input_string = "";
900 return ZERO;
901 }
902 } catch (IOException ioe) {
903 jrt_input_string = "";
904 return MINUS_ONE;
905 }
906 }
907
908
909
910
911
912
913 public String jrtGetInputString() {
914 return jrt_input_string;
915 }
916
917
918
919
920
921
922 public Map<String, PrintStream> getOutputFiles() {
923 return outputFiles;
924 }
925
926
927
928
929
930
931
932
933
934 public final PrintStream jrtGetPrintStream(String filename, boolean append) {
935 PrintStream ps = outputFiles.get(filename);
936 if (ps == null) {
937 try {
938 outputFiles.put(filename, ps = new PrintStream(new FileOutputStream(filename, append), true));
939 } catch (IOException ioe) {
940 throw new AwkRuntimeException("Cannot open " + filename + " for writing: " + ioe);
941 }
942 }
943 assert ps != null;
944 return ps;
945 }
946
947
948
949
950
951
952
953
954 public boolean jrtConsumeFileInput(String filename) throws IOException {
955 PartitioningReader pr = file_readers.get(filename);
956 if (pr == null) {
957 try {
958 file_readers.put(filename, pr = new PartitioningReader(new FileReader(filename), vm.getRS().toString()));
959 vm.setFILENAME(filename);
960 } catch (IOException ioe) {
961 LOG.warn("IO Exception", ioe);
962 file_readers.remove(filename);
963 throw ioe;
964 }
965 }
966
967 inputLine = pr.readRecord();
968 if (inputLine == null) {
969 return false;
970 } else {
971 jrt_input_string = inputLine;
972 vm.incNR();
973 return true;
974 }
975 }
976
977 private static Process spawnProcess(String cmd) throws IOException {
978
979 Process p;
980
981 if (IS_WINDOWS) {
982
983 ProcessBuilder pb = new ProcessBuilder(("cmd.exe /c " + cmd).split("[ \t]+"));
984 p = pb.start();
985 } else {
986
987 ProcessBuilder pb = new ProcessBuilder(cmd.split("[ \t]+"));
988 p = pb.start();
989 }
990
991 return p;
992 }
993
994
995
996
997
998
999
1000
1001 public boolean jrtConsumeCommandInput(String cmd) throws IOException {
1002 PartitioningReader pr = command_readers.get(cmd);
1003 if (pr == null) {
1004 try {
1005 Process p = spawnProcess(cmd);
1006
1007 p.getOutputStream().close();
1008 DataPump.dump(cmd, p.getErrorStream(), System.err);
1009 command_processes.put(cmd, p);
1010 command_readers.put(cmd, pr = new PartitioningReader(new InputStreamReader(p.getInputStream()), vm.getRS().toString()));
1011 vm.setFILENAME("");
1012 } catch (IOException ioe) {
1013 LOG.warn("IO Exception", ioe);
1014 command_readers.remove(cmd);
1015 Process p = command_processes.get(cmd);
1016 command_processes.remove(cmd);
1017 if (p != null) {
1018 p.destroy();
1019 }
1020 throw ioe;
1021 }
1022 }
1023
1024 inputLine = pr.readRecord();
1025 if (inputLine == null) {
1026 return false;
1027 } else {
1028 jrt_input_string = inputLine;
1029 vm.incNR();
1030 return true;
1031 }
1032 }
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043 public PrintStream jrtSpawnForOutput(String cmd) {
1044 PrintStream ps = output_streams.get(cmd);
1045 if (ps == null) {
1046 Process p;
1047 try {
1048 p = spawnProcess(cmd);
1049 DataPump.dump(cmd, p.getErrorStream(), System.err);
1050 DataPump.dump(cmd, p.getInputStream(), System.out);
1051 } catch (IOException ioe) {
1052 throw new AwkRuntimeException("Can't spawn " + cmd + ": " + ioe);
1053 }
1054 output_processes.put(cmd, p);
1055 output_streams.put(cmd, ps = new PrintStream(p.getOutputStream(), true));
1056 }
1057 return ps;
1058 }
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075 public Integer jrtClose(String filename) {
1076 boolean b1 = jrtCloseFileReader(filename);
1077 boolean b2 = jrtCloseCommandReader(filename);
1078 boolean b3 = jrtCloseOutputFile(filename);
1079 boolean b4 = jrtCloseOutputStream(filename);
1080
1081 return (b1 || b2 || b3 || b4) ? ZERO : MINUS_ONE;
1082 }
1083
1084
1085
1086
1087 public void jrtCloseAll() {
1088 Set<String> set = new HashSet<String>();
1089 for (String s : file_readers.keySet()) {
1090 set.add(s);
1091 }
1092 for (String s : command_readers.keySet()) {
1093 set.add(s);
1094 }
1095 for (String s : outputFiles.keySet()) {
1096 set.add(s);
1097 }
1098 for (String s : output_streams.keySet()) {
1099 set.add(s);
1100 }
1101 for (String s : set) {
1102 jrtClose(s);
1103 }
1104 }
1105
1106 private boolean jrtCloseOutputFile(String filename) {
1107 PrintStream ps = outputFiles.get(filename);
1108 if (ps != null) {
1109 ps.close();
1110 outputFiles.remove(filename);
1111 }
1112 return ps != null;
1113 }
1114
1115 private boolean jrtCloseOutputStream(String cmd) {
1116 Process p = output_processes.get(cmd);
1117 PrintStream ps = output_streams.get(cmd);
1118 if (ps == null) {
1119 return false;
1120 }
1121 assert p != null;
1122 output_processes.remove(cmd);
1123 output_streams.remove(cmd);
1124 ps.close();
1125
1126 if (!IS_WINDOWS) {
1127 try {
1128
1129 p.waitFor();
1130 p.exitValue();
1131 } catch (InterruptedException ie) {
1132 throw new AwkRuntimeException("Caught exception while waiting for process exit: " + ie);
1133 }
1134 }
1135 return true;
1136 }
1137
1138 private boolean jrtCloseFileReader(String filename) {
1139 PartitioningReader pr = file_readers.get(filename);
1140 if (pr == null) {
1141 return false;
1142 }
1143 file_readers.remove(filename);
1144 try {
1145 pr.close();
1146 return true;
1147 } catch (IOException ioe) {
1148 return false;
1149 }
1150 }
1151
1152 private boolean jrtCloseCommandReader(String cmd) {
1153 Process p = command_processes.get(cmd);
1154 PartitioningReader pr = command_readers.get(cmd);
1155 if (pr == null) {
1156 return false;
1157 }
1158 assert p != null;
1159 command_readers.remove(cmd);
1160 command_processes.remove(cmd);
1161 try {
1162 pr.close();
1163
1164 if (!IS_WINDOWS) {
1165 try {
1166
1167 p.waitFor();
1168 p.exitValue();
1169 } catch (InterruptedException ie) {
1170 throw new AwkRuntimeException("Caught exception while waiting for process exit: " + ie);
1171 }
1172 }
1173 return true;
1174 } catch (IOException ioe) {
1175 return false;
1176 }
1177 }
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192 public static Integer jrtSystem(String cmd) {
1193 try {
1194 Process p = spawnProcess(cmd);
1195
1196 p.getOutputStream().close();
1197 DataPump.dump(cmd, p.getErrorStream(), System.err);
1198 DataPump.dump(cmd, p.getInputStream(), System.out);
1199 try {
1200 int retcode = p.waitFor();
1201 return Integer.valueOf(retcode);
1202 } catch (InterruptedException ie) {
1203 return Integer.valueOf(p.exitValue());
1204 }
1205 } catch (IOException ioe) {
1206 LOG.warn("IO Exception", ioe);
1207 return MINUS_ONE;
1208 }
1209 }
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220 public static String sprintfNoCatch(Locale locale, String fmt_arg, Object... arr)
1221 throws IllegalFormatException
1222 {
1223 return String.format(locale, fmt_arg, arr);
1224 }
1225
1226
1227
1228
1229
1230
1231
1232
1233 public static void printfNoCatch(Locale locale, String fmt_arg, Object... arr) {
1234 System.out.print(sprintfNoCatch(locale, fmt_arg, arr));
1235 }
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245 public static void printfNoCatch(PrintStream ps, Locale locale, String fmt_arg, Object... arr) {
1246 ps.print(sprintfNoCatch(locale, fmt_arg, arr));
1247 }
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260 public static Integer replaceFirst(Object orig_value_obj, Object repl_obj, Object ere_obj, StringBuffer sb, String convfmt, Locale locale) {
1261 String orig_value = toAwkString(orig_value_obj, convfmt, locale);
1262 String repl = toAwkString(repl_obj, convfmt, locale);
1263 String ere = toAwkString(ere_obj, convfmt, locale);
1264
1265 repl = Matcher.quoteReplacement(repl);
1266 sb.setLength(0);
1267 sb.append(orig_value.replaceFirst(ere, repl));
1268 if (sb.toString().equals(orig_value)) {
1269 return ZERO;
1270 } else {
1271 return ONE;
1272 }
1273 }
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286 public static Integer replaceAll(Object orig_value_obj, Object repl_obj, Object ere_obj, StringBuffer sb, String convfmt, Locale locale) {
1287 String orig_value = toAwkString(orig_value_obj, convfmt, locale);
1288 String repl = toAwkString(repl_obj, convfmt, locale);
1289 String ere = toAwkString(ere_obj, convfmt, locale);
1290
1291 repl = Matcher.quoteReplacement(repl);
1292 sb.setLength(0);
1293
1294 Pattern p = Pattern.compile(ere);
1295 Matcher m = p.matcher(orig_value);
1296 int cnt = 0;
1297 while (m.find()) {
1298 ++cnt;
1299 m.appendReplacement(sb, repl);
1300 }
1301 m.appendTail(sb);
1302 return Integer.valueOf(cnt);
1303 }
1304
1305
1306
1307
1308
1309
1310
1311
1312 public static String substr(Object startpos_obj, String str) {
1313 int startpos = (int) toDouble(startpos_obj);
1314 if (startpos <= 0) {
1315 throw new AwkRuntimeException("2nd arg to substr must be a positive integer");
1316 }
1317 if (startpos > str.length()) {
1318 return "";
1319 } else {
1320 return str.substring(startpos - 1);
1321 }
1322 }
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332 public static String substr(Object size_obj, Object startpos_obj, String str) {
1333 int startpos = (int) toDouble(startpos_obj);
1334 if (startpos <= 0) {
1335 throw new AwkRuntimeException("2nd arg to substr must be a positive integer");
1336 }
1337 if (startpos > str.length()) {
1338 return "";
1339 }
1340 int size = (int) toDouble(size_obj);
1341 if (size < 0) {
1342 throw new AwkRuntimeException("3nd arg to substr must be a non-negative integer");
1343 }
1344 if (startpos + size > str.length()) {
1345 return str.substring(startpos - 1);
1346 } else {
1347 return str.substring(startpos - 1, startpos + size - 1);
1348 }
1349 }
1350
1351
1352
1353
1354
1355
1356 public static int timeSeed() {
1357 long l = (new Date()).getTime();
1358 long l2 = (l % (1000 * 60 * 60 * 24));
1359 int seed = (int) l2;
1360 return seed;
1361 }
1362
1363
1364
1365
1366
1367
1368
1369 public static Random newRandom(int seed) {
1370 return new Random(seed);
1371 }
1372
1373
1374
1375
1376
1377
1378 public void applyRS(Object rs_obj) {
1379
1380
1381 if (partitioningReader != null) {
1382 partitioningReader.setRecordSeparator(rs_obj.toString());
1383 }
1384 }
1385 }