1 /***********************************************************************
2 * *
3 * This software is part of the ast package *
4 * Copyright (c) 1985-2010 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Common Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
8 * *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
12 * *
13 * Information and Software Systems Research *
14 * AT&T Research *
15 * Florham Park NJ *
16 * *
17 * Glenn Fowler <gsf@research.att.com> *
18 * David Korn <dgk@research.att.com> *
19 * Phong Vo <kpv@research.att.com> *
20 * *
21 ***********************************************************************/
22 #pragma prototyped
23
24 /*
25 * return the record format descriptor given a format string
26 * e!=0 set to the first unrecognized char after the format
27 * REC_N_TYPE() returned on error
28 *
29 * d[0xNN|delimiter] (delimited, newline default)
30 * [f][+]size (fixed length)
31 * v hN oN zN b|l i|n (variable length with size header)
32 * h header size in bytes (ibm V 4)
33 * o size offset in bytes (ibm V 0)
34 * z size length in bytes (ibm V 2)
35 * l|b little-endian or big-endian size (ibm V b (0))
36 * i|n header included/not-included in size (ibm V i (1))
37 */
38
39 #include <recfmt.h>
40 #include <ctype.h>
41
42 Recfmt_t
recstr(register const char * s,char ** e)43 recstr(register const char* s, char** e)
44 {
45 char* t;
46 int n;
47 long v;
48 int a[6];
49
50 while (*s == ' ' || *s == '\t' || *s == ',')
51 s++;
52 switch (*s)
53 {
54 case 'd':
55 case 'D':
56 if (!*s)
57 n = '\n';
58 else
59 {
60 if (*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))
61 n = (int)strtol(s, &t, 0);
62 else
63 n = chresc(s, &t);
64 s = (const char*)t;
65 }
66 if (e)
67 *e = (char*)s;
68 return REC_D_TYPE(n);
69 case 'f':
70 case 'F':
71 while (*++s == ' ' || *s == '\t' || *s == ',');
72 /*FALLTHROUGH*/
73 case '+':
74 case '0': case '1': case '2': case '3': case '4':
75 case '5': case '6': case '7': case '8': case '9':
76 n = strton(s, &t, NiL, 0);
77 if (n > 0 && t > (char*)s)
78 {
79 if (e)
80 *e = t;
81 return REC_F_TYPE(n);
82 }
83 break;
84 case 'm':
85 case 'M':
86 while (*++s == ' ' || *s == '\t' || *s == ',');
87 for (t = (char*)s; *t && *t != ' ' && *t != '\t' && *t != ','; t++);
88 if ((t - s) == 4)
89 {
90 if (strneq(s, "data", 4))
91 {
92 if (e)
93 *e = t;
94 return REC_M_TYPE(REC_M_data);
95 }
96 else if (strneq(s, "path", 4))
97 {
98 if (e)
99 *e = t;
100 return REC_M_TYPE(REC_M_path);
101 }
102 }
103
104 /*
105 * TBD: look up name in method libraries
106 * and assign an integer index
107 */
108
109 break;
110 case 'u':
111 case 'U':
112 while (*++s == ' ' || *s == '\t' || *s == ',');
113 n = strtol(s, &t, 0);
114 if (n < 0 || n > 15 || *t++ != '.')
115 break;
116 v = strtol(t, &t, 0);
117 if (*t)
118 break;
119 if (e)
120 *e = t;
121 return REC_U_TYPE(n, v);
122 case 'v':
123 case 'V':
124 a[0] = 0;
125 a[1] = 4;
126 a[2] = 0;
127 a[3] = 2;
128 a[4] = 0;
129 a[5] = 1;
130 n = 0;
131 for (;;)
132 {
133 switch (*++s)
134 {
135 case 0:
136 break;
137 case 'm':
138 case 'M':
139 n = 0;
140 continue;
141 case 'h':
142 case 'H':
143 n = 1;
144 continue;
145 case 'o':
146 case 'O':
147 n = 2;
148 continue;
149 case 'z':
150 case 'Z':
151 n = 3;
152 continue;
153 case 'b':
154 case 'B':
155 n = 4;
156 a[n++] = 0;
157 continue;
158 case 'l':
159 case 'L':
160 n = 4;
161 a[n++] = 1;
162 continue;
163 case 'n':
164 case 'N':
165 n = 0;
166 a[5] = 0;
167 continue;
168 case 'i':
169 case 'I':
170 n = 0;
171 a[5] = 1;
172 continue;
173 case ' ':
174 case '\t':
175 case ',':
176 case '-':
177 case '+':
178 continue;
179 case '0': case '1': case '2': case '3': case '4':
180 case '5': case '6': case '7': case '8': case '9':
181 v = 0;
182 a[n++] = strtol(s, &t, 0);
183 s = (const char*)t - 1;
184 continue;
185 }
186 break;
187 }
188 if (e)
189 *e = (char*)s;
190 if (a[3] > (a[1] - a[2]))
191 a[3] = a[1] - a[2];
192 return REC_V_RECORD(REC_V_TYPE(a[1], a[2], a[3], a[4], a[5]), a[0]);
193 case '%':
194 if (e)
195 *e = (char*)s + 1;
196 return REC_M_TYPE(REC_M_path);
197 case '-':
198 case '?':
199 if (e)
200 *e = (char*)s + 1;
201 return REC_M_TYPE(REC_M_data);
202 }
203 if (e)
204 *e = (char*)s;
205 return REC_N_TYPE();
206 }
207