1 /*
2 * $Id: collec.i,v 1.1 2005-09-18 22:05:54 dhmunro Exp $
3 * Collect variables through all times in a time history file.
4 */
5 /* Copyright (c) 2005, The Regents of the University of California.
6 * All rights reserved.
7 * This file is part of yorick (http://yorick.sourceforge.net).
8 * Read the accompanying LICENSE file for details.
9 */
10
collect(f,name)11 func collect(f, name)
12 /* DOCUMENT result= collect(f, name_string)
13 scans through all records of the history file F accumulating the
14 variable NAME_STRING into a single array with one additional
15 index varying from 1 to the number of records.
16
17 NAME_STRING can be either a simple variable name, or a name
18 followed by up to four simple indices which are either nil, an
19 integer, or an index range with constant limits. (Note that
20 0 or negative indices count from the end of a dimension.)
21
22 Examples:
23 collect(f, "xle") -- collects the variable f.xle
24 collect(f, "tr(2,2:)") -- collects f.tr(2,2:)
25 collect(f, "akap(2,-1:0,)") -- collects f.akap(2,-1:0,)
26 (i.e.- akap in the last two values of its
27 second index)
28
29 SEE ALSO: get_times
30 */
31 {
32 name= strtok(name, " \t(");
33 var= name(1);
34 name= name(2);
35
36 /* this is yucky -- need a query function for current record number */
37 n0= where(strmatch(print(f),"Current record"));
38 n= 0;
39 if (numberof(n0)) {
40 n0= n0(1);
41 sread, print(f)(n0), n0,n, format=" Current record is number %ld of %ld";
42 } else {
43 error, "no record structure for file?";
44 }
45
46 local a,b,c,d,e,name;
47
48 if (!collect_get(a, name)) {
49 jr, f, 1;
50 rslt= array(get_member(f,var), n);
51 for (i=2 ; i<=n ; i++) {
52 jr, f, i;
53 rslt(.., i)= get_member(f,var);
54 }
55 } else if (!collect_get(b, name)) {
56 jr, f, 1;
57 rslt= array(get_member(f,var)(a), n);
58 for (i=2 ; i<=n ; i++) {
59 jr, f, i;
60 rslt(.., i)= get_member(f,var)(a);
61 }
62 } else if (!collect_get(c, name)) {
63 jr, f, 1;
64 rslt= array(get_member(f,var)(a, b), n);
65 for (i=2 ; i<=n ; i++) {
66 jr, f, i;
67 rslt(.., i)= get_member(f,var)(a, b);
68 }
69 } else if (!collect_get(d, name)) {
70 jr, f, 1;
71 rslt= array(get_member(f,var)(a, b, c), n);
72 for (i=2 ; i<=n ; i++) {
73 jr, f, i;
74 rslt(.., i)= get_member(f,var)(a, b, c);
75 }
76 } else if (!collect_get(e, name)) {
77 jr, f, 1;
78 rslt= array(get_member(f,var)(a, b, c, d), n);
79 for (i=2 ; i<=n ; i++) {
80 jr, f, i;
81 rslt(.., i)= get_member(f,var)(a, b, c, d);
82 }
83 } else {
84 error, "too many (>4) subscripts for collect";
85 }
86
87 jr, f, n0;
88 return rslt;
89 }
90
91 func collect_get(&ndx, &name)
92 {
93 if (!name) return 0;
94
95 argc= *pointer(name);
96 list= where(argc==',' | argc==')');
97 if (numberof(list)) {
98 list= list(1);
99 arg= list>1? strpart(name,1:list-1) : "";
100 name= list<strlen(name)? strpart(name,list+1:0) : string(0);
101 } else {
102 arg= name;
103 name= string(0);
104 }
105
106 argc= *pointer(arg);
107 list= where(argc==':');
108 n= numberof(list);
109
110 if (n==0) {
111 ndx= collect_num(arg);
112 return 1;
113
114 } else {
115 l= list(1);
116 mn= l<2? [] : collect_num(strpart(arg, 1:l-1));
117 if (n==1) m= 1;
118 else m= list(2);
119 mx= l>=strlen(arg)? [] : collect_num(strpart(arg, l+1:m-1));
120 if (n==1) {
121 ndx= collect_rng(mn:mx);
122 return 2;
123 } else if (n==2) {
124 inc= m>=strlen(arg)? [] : collect_num(strpart(arg, m+1:0));
125 ndx= collect_rng(mn:mx:inc);
126 return 3;
127 }
128 }
129
130 error, "index garbled or too complicated";
131 return 0;
132 }
133
collect_num(text)134 func collect_num(text)
135 {
136 val= 0;
137 s= string(0);
138 n= sread(format="%ld%[^ \t\n]", text, val, s);
139 if (n==1) return val;
140 if (n==0 && !strtok(text," \t")(1)) return [];
141 error, "index too complicated-- not nil, number, or const range";
142 return string(0);
143 }
144
collect_rng(x)145 func collect_rng(x) { return x; }
146