Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/cmd/dsslib/fix/fix.c
1810 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 2003-2011 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Glenn Fowler <[email protected]> *
18
* *
19
***********************************************************************/
20
#pragma prototyped
21
22
static const char usage[] =
23
"[+DESCRIPTION?The fix query generates a fixed binary flat schema from the"
24
" input file schema on the standard output. If the input schema is"
25
" variable width then the input file is used to estimate average and"
26
" maximum field widths. The generated schema may be used as input for"
27
" the \bflat\b method conversion query.]"
28
"[s:stamp?The identification date stamp.]:[stamp:=YYYY-MM-DD]"
29
;
30
31
#include <dsslib.h>
32
#include <tm.h>
33
34
#define FIELD_string 0
35
#define FIELD_number 1
36
#define FIELD_buffer 2
37
38
struct Field_s; typedef struct Field_s Field_t;
39
struct State_s; typedef struct State_s State_t;
40
41
struct Field_s
42
{
43
Dtlink_t link;
44
Field_t* train;
45
Cxvariable_t* variable;
46
Cxnumber_t max;
47
size_t width;
48
int representation;
49
int flags;
50
};
51
52
struct State_s
53
{
54
Dtdisc_t fielddisc;
55
Vmalloc_t* vm;
56
Field_t* train;
57
Dt_t* fields;
58
char* stamp;
59
};
60
61
static int
62
fieldcmp(Dt_t* dt, void* a, void* b, Dtdisc_t* disc)
63
{
64
register Field_t* fa = (Field_t*)a;
65
register Field_t* fb = (Field_t*)b;
66
67
if (fa->representation < fb->representation)
68
return -1;
69
if (fa->representation > fb->representation)
70
return 1;
71
if (fa->width < fb->width)
72
return 1;
73
if (fa->width > fb->width)
74
return -1;
75
return strcmp(fa->variable->name, fb->variable->name);
76
}
77
78
extern Dsslib_t dss_lib_fix;
79
80
static int
81
fix_beg(Cx_t* cx, Cxexpr_t* expr, void* data, Cxdisc_t* disc)
82
{
83
char** argv = (char**)data;
84
int errors = error_info.errors;
85
char* s;
86
State_t* state;
87
Cxvariable_t* variable;
88
Field_t* field;
89
Vmalloc_t* vm;
90
91
if (!(vm = vmopen(Vmdcheap, Vmlast, 0)) || !(state = vmnewof(vm, 0, State_t, 1, 0)))
92
{
93
if (vm)
94
vmclose(vm);
95
if (disc->errorf)
96
(*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "out of space");
97
return -1;
98
}
99
state->vm = vm;
100
if (dssoptlib(cx->buf, &dss_lib_fix, usage, disc))
101
goto bad;
102
s = sfstruse(cx->buf);
103
for (;;)
104
{
105
switch (optget(argv, s))
106
{
107
case 's':
108
if (!(state->stamp = strdup(opt_info.arg)))
109
{
110
if (disc->errorf)
111
(*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "out of space");
112
return -1;
113
}
114
continue;
115
case '?':
116
if (disc->errorf)
117
(*disc->errorf)(NiL, disc, ERROR_USAGE|4, "%s", opt_info.arg);
118
else
119
goto bad;
120
continue;
121
case ':':
122
if (disc->errorf)
123
(*disc->errorf)(NiL, disc, 2, "%s", opt_info.arg);
124
else
125
goto bad;
126
continue;
127
}
128
break;
129
}
130
if (error_info.errors > errors)
131
goto bad;
132
argv += opt_info.index;
133
state->fielddisc.comparf = fieldcmp;
134
if (!(state->fields = dtnew(vm, &state->fielddisc, Dtoset)))
135
{
136
if (disc->errorf)
137
(*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "out of space");
138
goto bad;
139
}
140
for (variable = (Cxvariable_t*)dtfirst(cx->fields); variable; variable = (Cxvariable_t*)dtnext(cx->fields, variable))
141
{
142
if (!(field = vmnewof(vm, 0, Field_t, 1, 0)))
143
{
144
if (disc->errorf)
145
(*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "out of space");
146
goto bad;
147
}
148
field->variable = variable;
149
switch (variable->type->representation)
150
{
151
case CX_buffer:
152
field->representation = FIELD_buffer;
153
break;
154
case CX_string:
155
field->representation = FIELD_string;
156
break;
157
default:
158
field->representation = FIELD_number;
159
break;
160
}
161
if (field->width = variable->format.width)
162
{
163
field->flags = variable->format.flags;
164
dtinsert(state->fields, field);
165
}
166
else if (field->width = variable->type->format.width)
167
{
168
field->flags = variable->type->format.flags;
169
dtinsert(state->fields, field);
170
}
171
else
172
{
173
field->train = state->train;
174
state->train = field;
175
}
176
}
177
expr->data = state;
178
return 0;
179
bad:
180
vmclose(vm);
181
return -1;
182
}
183
184
static int
185
fix_act(Cx_t* cx, Cxexpr_t* expr, void* data, Cxdisc_t* disc)
186
{
187
register State_t* state = (State_t*)expr->data;
188
register Field_t* field;
189
Cxoperand_t arg;
190
191
for (field = state->train; field; field = field->train)
192
{
193
if (cxcast(cx, &arg, field->variable, field->variable->type, data, NiL))
194
return -1;
195
if (field->representation == FIELD_number)
196
{
197
if (arg.value.number < 0)
198
{
199
arg.value.number = -arg.value.number;
200
field->flags = CX_UNSIGNED;
201
}
202
if (field->max < arg.value.number)
203
field->max = arg.value.number;
204
}
205
else if (field->width < arg.value.buffer.size)
206
{
207
error(-1, "AHA fix_act %s.width %d arg.size %d", field->variable->name, field->width, arg.value.buffer.size);
208
field->width = arg.value.buffer.size;
209
}
210
}
211
return 0;
212
}
213
214
static int
215
fix_end(Cx_t* cx, Cxexpr_t* expr, void* data, Cxdisc_t* disc)
216
{
217
register State_t* state = (State_t*)expr->data;
218
register Field_t* field;
219
register size_t w;
220
register size_t x;
221
register size_t r;
222
register size_t b;
223
Dsslib_t* lib;
224
char* s;
225
226
b = 0;
227
for (field = state->train; field; field = field->train)
228
{
229
if (field->representation == FIELD_number)
230
{
231
if (field->max != (Cxinteger_t)field->max)
232
{
233
field->width = 8;
234
field->flags = CX_FLOAT;
235
}
236
else
237
{
238
field->flags ^= CX_UNSIGNED|CX_INTEGER;
239
if (field->max > (unsigned long)0xffffffff)
240
field->width = 8;
241
else if (field->max > (unsigned long)0xffff)
242
field->width = 4;
243
else
244
field->width = 2;
245
}
246
}
247
else
248
{
249
if ((w = (field->width * 3) / 2) < 8)
250
w = 8;
251
else if (w < (1<<15))
252
for (x = w, w = 1; w < x; w <<= 1);
253
error(-1, "AHA fix_end %s.width %d w %d", field->variable->name, field->width, w);
254
if (field->representation == FIELD_string)
255
field->width = w;
256
else
257
{
258
b += w;
259
field->width = 4;
260
}
261
}
262
dtinsert(state->fields, field);
263
}
264
r = 0;
265
for (field = (Field_t*)dtfirst(state->fields); field; field = (Field_t*)dtnext(state->fields, field))
266
r += field->width;
267
x = r;
268
if ((r += 2 * b) < 16)
269
r = 16;
270
else if (r < (1<<15))
271
for (w = r, r = 1; r < w; r <<= 1);
272
sfprintf(expr->op, "<METHOD>flat</>\n");
273
sfprintf(expr->op, "<FLAT>\n");
274
sfprintf(expr->op, " <NAME>%s</>\n", DSS(cx)->meth->name);
275
s = (char*)DSS(cx)->meth->description;
276
if ((w = strlen(s)) && s[w-1] == '.')
277
w--;
278
sfprintf(expr->op, " <DESCRIPTION>%-*.*s fixed width binary format.</>\n", w, w, s);
279
if (!state->stamp)
280
state->stamp = fmttime("%Y-%m-%d", time(NiL));
281
sfprintf(expr->op, " <IDENT>@(#)$Id: %s bin %s $</>\n", DSS(cx)->meth->name, state->stamp);
282
sfprintf(expr->op, " <MAGIC>\n");
283
sfprintf(expr->op, " <STRING>%s</>\n", DSS(cx)->meth->name);
284
sfprintf(expr->op, " <VERSION>");
285
for (s = state->stamp; *s; s++)
286
if (isdigit(*s))
287
sfputc(expr->op, *s);
288
sfprintf(expr->op, "</>\n");
289
sfprintf(expr->op, " <SWAP>be</>\n");
290
sfprintf(expr->op, " </>\n");
291
sfprintf(expr->op, " <COMPRESS>pzip %s-bin</>\n", DSS(cx)->meth->name);
292
w = 0;
293
for (lib = (Dsslib_t*)dtfirst(cx->state->libraries); lib; lib = (Dsslib_t*)dtnext(cx->state->libraries, lib))
294
if (lib->types && !lib->meth)
295
{
296
sfprintf(expr->op, " <LIBRARY>%s</>\n", lib->name);
297
if (!w && streq(lib->name, "num_t"))
298
w = 1;
299
}
300
if (!w)
301
sfprintf(expr->op, " <LIBRARY>num_t</>\n");
302
for (field = (Field_t*)dtfirst(state->fields); field; field = (Field_t*)dtnext(state->fields, field))
303
{
304
sfprintf(expr->op, " <FIELD>\n");
305
sfprintf(expr->op, " <NAME>%s</>\n", field->variable->name);
306
sfprintf(expr->op, " <DESCRIPTION>%s</>\n", field->variable->description);
307
sfprintf(expr->op, " <TYPE>%s</>\n", field->variable->type->name);
308
sfprintf(expr->op, " <PHYSICAL>\n");
309
switch (field->representation)
310
{
311
case FIELD_buffer:
312
sfprintf(expr->op, " <TYPE>buffer</>\n");
313
break;
314
case FIELD_number:
315
if (field->flags & CX_UNSIGNED)
316
sfprintf(expr->op, " <TYPE>unsigned be_t</>\n");
317
else if (field->flags & CX_INTEGER)
318
sfprintf(expr->op, " <TYPE>be_t</>\n");
319
else
320
sfprintf(expr->op, " <TYPE>ibm_t</>\n");
321
break;
322
}
323
sfprintf(expr->op, " <WIDTH>%d</>\n", field->width);
324
sfprintf(expr->op, " </>\n");
325
sfprintf(expr->op, " </>\n");
326
}
327
if (r > x)
328
{
329
sfprintf(expr->op, " <FIELD>\n");
330
sfprintf(expr->op, " <NAME>%s</>\n", b ? "_HEAP_" : "_PAD_");
331
sfprintf(expr->op, " <DESCRIPTION>%s</>\n", b ? "Variable width data heap." : "Fixed size roundup pad.");
332
sfprintf(expr->op, " <TYPE>void</>\n");
333
sfprintf(expr->op, " <PHYSICAL>\n");
334
sfprintf(expr->op, " <WIDTH>%I*u</>\n", sizeof(r), r - x);
335
sfprintf(expr->op, " </>\n");
336
sfprintf(expr->op, " </>\n");
337
}
338
sfprintf(expr->op, "</>\n");
339
vmclose(state->vm);
340
return 0;
341
}
342
343
static Cxquery_t queries[] =
344
{
345
{
346
"fix",
347
"generate fixed binary schema from input schema",
348
CXH,
349
fix_beg,
350
0,
351
fix_act,
352
fix_end
353
},
354
{0}
355
};
356
357
Dsslib_t dss_lib_fix =
358
{
359
"fix",
360
"fix query"
361
"[-1lms5P?\n@(#)$Id: dss fix query (AT&T Research) 2003-01-30 $\n]"
362
USAGE_LICENSE,
363
CXH,
364
0,
365
0,
366
0,
367
0,
368
0,
369
0,
370
&queries[0]
371
};
372
373