see5-installer 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +8 -0
- data/.rubocop.yml +11 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +10 -0
- data/README.md +29 -0
- data/Rakefile +12 -0
- data/ext/c5.0/Makefile +86 -0
- data/ext/c5.0/attwinnow.c +394 -0
- data/ext/c5.0/c50.c +330 -0
- data/ext/c5.0/classify.c +700 -0
- data/ext/c5.0/confmat.c +195 -0
- data/ext/c5.0/construct.c +853 -0
- data/ext/c5.0/contin.c +613 -0
- data/ext/c5.0/defns.i +788 -0
- data/ext/c5.0/discr.c +307 -0
- data/ext/c5.0/extern.i +170 -0
- data/ext/c5.0/formrules.c +720 -0
- data/ext/c5.0/formtree.c +1158 -0
- data/ext/c5.0/getdata.c +521 -0
- data/ext/c5.0/getnames.c +733 -0
- data/ext/c5.0/global.c +211 -0
- data/ext/c5.0/gpl.txt +674 -0
- data/ext/c5.0/implicitatt.c +1112 -0
- data/ext/c5.0/info.c +146 -0
- data/ext/c5.0/mcost.c +138 -0
- data/ext/c5.0/modelfiles.c +952 -0
- data/ext/c5.0/p-thresh.c +313 -0
- data/ext/c5.0/prune.c +1069 -0
- data/ext/c5.0/report.c +345 -0
- data/ext/c5.0/rules.c +579 -0
- data/ext/c5.0/ruletree.c +398 -0
- data/ext/c5.0/siftrules.c +1285 -0
- data/ext/c5.0/sort.c +156 -0
- data/ext/c5.0/subset.c +599 -0
- data/ext/c5.0/text.i +223 -0
- data/ext/c5.0/trees.c +740 -0
- data/ext/c5.0/update.c +129 -0
- data/ext/c5.0/utility.c +1146 -0
- data/ext/c5.0/xval +150 -0
- data/ext/c5.0/xval.c +402 -0
- data/ext/gritbot/Makefile +98 -0
- data/ext/gritbot/check.c +1110 -0
- data/ext/gritbot/cluster.c +342 -0
- data/ext/gritbot/common.c +1269 -0
- data/ext/gritbot/continatt.c +412 -0
- data/ext/gritbot/defns.i +623 -0
- data/ext/gritbot/discratt.c +459 -0
- data/ext/gritbot/extern.i +101 -0
- data/ext/gritbot/getdata.c +329 -0
- data/ext/gritbot/getnames.c +573 -0
- data/ext/gritbot/global.c +104 -0
- data/ext/gritbot/gpl.txt +674 -0
- data/ext/gritbot/gritbot.c +295 -0
- data/ext/gritbot/implicitatt.c +1108 -0
- data/ext/gritbot/inspect.c +794 -0
- data/ext/gritbot/modelfiles.c +687 -0
- data/ext/gritbot/outlier.c +415 -0
- data/ext/gritbot/sort.c +130 -0
- data/ext/gritbot/text.i +159 -0
- data/ext/gritbot/update.c +126 -0
- data/ext/gritbot/utility.c +1029 -0
- data/ext/see5-installer/extconf.rb +25 -0
- data/lib/see5/installer.rb +10 -0
- data/lib/see5/installer/version.rb +7 -0
- data/see5-installer.gemspec +30 -0
- metadata +115 -0
@@ -0,0 +1,687 @@
|
|
1
|
+
/*************************************************************************/
|
2
|
+
/* */
|
3
|
+
/* Copyright 2010 Rulequest Research Pty Ltd. */
|
4
|
+
/* */
|
5
|
+
/* This file is part of GritBot GPL Edition, a single-threaded version */
|
6
|
+
/* of GritBot release 2.01. */
|
7
|
+
/* */
|
8
|
+
/* GritBot GPL Edition is free software: you can redistribute it */
|
9
|
+
/* and/or modify it under the terms of the GNU General Public License */
|
10
|
+
/* as published by the Free Software Foundation, either version 3 of */
|
11
|
+
/* the License, or (at your option) any later version. */
|
12
|
+
/* */
|
13
|
+
/* GritBot GPL Edition is distributed in the hope that it will be */
|
14
|
+
/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
|
15
|
+
/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
|
16
|
+
/* GNU General Public License for more details. */
|
17
|
+
/* */
|
18
|
+
/* You should have received a copy of the GNU General Public License */
|
19
|
+
/* (gpl.txt) along with GritBot GPL Edition. If not, see */
|
20
|
+
/* */
|
21
|
+
/* <http://www.gnu.org/licenses/>. */
|
22
|
+
/* */
|
23
|
+
/*************************************************************************/
|
24
|
+
|
25
|
+
|
26
|
+
|
27
|
+
/*************************************************************************/
|
28
|
+
/* */
|
29
|
+
/* Routines for saving and reading sift files */
|
30
|
+
/* ------------------------------------------ */
|
31
|
+
/* */
|
32
|
+
/*************************************************************************/
|
33
|
+
|
34
|
+
/* Formats:
|
35
|
+
|
36
|
+
1 <att> target att
|
37
|
+
2 <att> use logs with att
|
38
|
+
3 <att> <ltail> <htail> set low/high tail
|
39
|
+
|
40
|
+
11 <lev> <att> <br> split on attribute value
|
41
|
+
12 <lev> <att> <br> <cut> threshold test
|
42
|
+
13 <lev> <att> <br> <subset> subset test
|
43
|
+
|
44
|
+
21 <cov> <frac> <mode> [<val> <cf>]* 0 discrete cluster
|
45
|
+
22 <cov> <mean> <sd> <lfrac> <llim> <hfrac> <hlim> low/high contin cluster
|
46
|
+
|
47
|
+
clusters may be followed by one or more caveats of the form
|
48
|
+
<att> <low> <high> or
|
49
|
+
<att> <subset>
|
50
|
+
*/
|
51
|
+
|
52
|
+
#include "defns.i"
|
53
|
+
#include "extern.i"
|
54
|
+
|
55
|
+
int Entry;
|
56
|
+
|
57
|
+
char* Prop[]={"null",
|
58
|
+
"id",
|
59
|
+
"atts",
|
60
|
+
"att",
|
61
|
+
"sstat",
|
62
|
+
"elts",
|
63
|
+
"prec",
|
64
|
+
"label",
|
65
|
+
"def",
|
66
|
+
"minabnorm"
|
67
|
+
};
|
68
|
+
|
69
|
+
char PropName[20],
|
70
|
+
*PropVal=Nil,
|
71
|
+
*Unquoted;
|
72
|
+
int PropValSize=0;
|
73
|
+
|
74
|
+
#define PROPS 9
|
75
|
+
|
76
|
+
#define ERRORP 0
|
77
|
+
#define IDP 1
|
78
|
+
#define ATTSP 2
|
79
|
+
#define ATTP 3
|
80
|
+
#define SSTATP 4
|
81
|
+
#define ELTSP 5
|
82
|
+
#define PRECP 6
|
83
|
+
#define LABELP 7
|
84
|
+
#define DEFP 8
|
85
|
+
#define MINABNORMP 9
|
86
|
+
|
87
|
+
|
88
|
+
/*************************************************************************/
|
89
|
+
/* */
|
90
|
+
/* Check whether file is open. If it is not, open it and */
|
91
|
+
/* read/write header information and names */
|
92
|
+
/* */
|
93
|
+
/*************************************************************************/
|
94
|
+
|
95
|
+
|
96
|
+
void CheckFile(String Extension, Boolean Write)
|
97
|
+
/* --------- */
|
98
|
+
{
|
99
|
+
static char *LastExt="";
|
100
|
+
|
101
|
+
if ( ! Sf || strcmp(LastExt, Extension) )
|
102
|
+
{
|
103
|
+
LastExt = Extension;
|
104
|
+
|
105
|
+
if ( Sf )
|
106
|
+
{
|
107
|
+
fprintf(Sf, "\n");
|
108
|
+
fclose(Sf);
|
109
|
+
}
|
110
|
+
|
111
|
+
#ifdef INSPECT
|
112
|
+
ReadFilePrefix(Extension);
|
113
|
+
#else
|
114
|
+
if ( Write )
|
115
|
+
{
|
116
|
+
WriteFilePrefix(Extension);
|
117
|
+
}
|
118
|
+
else
|
119
|
+
{
|
120
|
+
ReadFilePrefix(Extension);
|
121
|
+
}
|
122
|
+
#endif
|
123
|
+
}
|
124
|
+
}
|
125
|
+
#ifndef INSPECT
|
126
|
+
|
127
|
+
|
128
|
+
|
129
|
+
/*************************************************************************/
|
130
|
+
/* */
|
131
|
+
/* Write information on system, parameters etc */
|
132
|
+
/* */
|
133
|
+
/*************************************************************************/
|
134
|
+
|
135
|
+
|
136
|
+
void WriteFilePrefix(String Extension)
|
137
|
+
/* --------------- */
|
138
|
+
{
|
139
|
+
time_t clock;
|
140
|
+
struct tm *now;
|
141
|
+
|
142
|
+
if ( ! (Sf = GetFile(Extension, "w")) )
|
143
|
+
{
|
144
|
+
Error(NOFILE, Fn, E_ForWrite);
|
145
|
+
}
|
146
|
+
|
147
|
+
clock = time(0);
|
148
|
+
now = localtime(&clock);
|
149
|
+
now->tm_mon++;
|
150
|
+
fprintf(Sf, "id=\"GritBot %s %d-%d%d-%d%d\"\n",
|
151
|
+
RELEASE,
|
152
|
+
now->tm_year + 1900,
|
153
|
+
now->tm_mon / 10, now->tm_mon % 10,
|
154
|
+
now->tm_mday / 10, now->tm_mday % 10);
|
155
|
+
|
156
|
+
SaveNames();
|
157
|
+
|
158
|
+
fprintf(Sf, "minabnorm=\"%g\"\n", MINABNORM);
|
159
|
+
}
|
160
|
+
|
161
|
+
|
162
|
+
|
163
|
+
void SaveCondition()
|
164
|
+
/* -------------- */
|
165
|
+
{
|
166
|
+
Attribute Att;
|
167
|
+
int CType, b, Bytes;
|
168
|
+
DiscrValue Br;
|
169
|
+
char SE[100];
|
170
|
+
|
171
|
+
if ( GEnv.Level < 0 ) return;
|
172
|
+
|
173
|
+
/* Save top condition */
|
174
|
+
|
175
|
+
Att = GEnv.Test[GEnv.Level].Att;
|
176
|
+
Br = GEnv.Test[GEnv.Level].Br;
|
177
|
+
|
178
|
+
/* Determine condition type */
|
179
|
+
|
180
|
+
CType = ( Br == 1 ? 11 :
|
181
|
+
Continuous(Att) || Ordered(Att) ? 12 :
|
182
|
+
Continuous(ClassAtt) && MaxAttVal[Att] > 3 ? 13 : 11 );
|
183
|
+
|
184
|
+
sprintf(SE, "%d %d %d %d", CType, GEnv.Level, Att, Br);
|
185
|
+
ExtendSiftEntry(SE);
|
186
|
+
|
187
|
+
/* Don't need to save anything else if this branch is 1 (N/A)
|
188
|
+
or if test is on two-valued discrete att */
|
189
|
+
|
190
|
+
if ( Br != 1 )
|
191
|
+
{
|
192
|
+
if ( Continuous(Att) || Ordered(Att) )
|
193
|
+
{
|
194
|
+
sprintf(SE, " %.8g", GEnv.Test[GEnv.Level].Cut);
|
195
|
+
ExtendSiftEntry(SE);
|
196
|
+
}
|
197
|
+
else
|
198
|
+
if ( Continuous(ClassAtt) && MaxAttVal[Att] > 3 )
|
199
|
+
{
|
200
|
+
/* Print subset of values */
|
201
|
+
|
202
|
+
Bytes = (MaxAttVal[Att]>>3) + 1;
|
203
|
+
|
204
|
+
ForEach(b, 0, Bytes-1)
|
205
|
+
{
|
206
|
+
sprintf(SE, " %x", GEnv.Test[GEnv.Level].Left[b]);
|
207
|
+
ExtendSiftEntry(SE);
|
208
|
+
}
|
209
|
+
}
|
210
|
+
}
|
211
|
+
|
212
|
+
ExtendSiftEntry("\n");
|
213
|
+
}
|
214
|
+
|
215
|
+
|
216
|
+
|
217
|
+
void SaveDiscrCluster(DiscrValue Expect, CaseCount Anoms, CaseCount Cases,
|
218
|
+
CaseCount *Freq)
|
219
|
+
/* ---------------- */
|
220
|
+
{
|
221
|
+
DiscrValue v;
|
222
|
+
float Xv;
|
223
|
+
char SE[100];
|
224
|
+
|
225
|
+
SaveCondition();
|
226
|
+
|
227
|
+
sprintf(SE, "21 %d %g %d",
|
228
|
+
Cases, (Cases - Anoms) / (Cases + 1E-3), Expect);
|
229
|
+
ExtendSiftEntry(SE);
|
230
|
+
|
231
|
+
ForEach(v, 1, MaxAttVal[ClassAtt])
|
232
|
+
{
|
233
|
+
if ( v == Expect ) continue;
|
234
|
+
|
235
|
+
Xv = XDScore(Freq[v], Cases, Anoms, Prior[ClassAtt][v]);
|
236
|
+
|
237
|
+
if ( Xv <= 1.0 / (MINABNORM * MINABNORM) )
|
238
|
+
{
|
239
|
+
sprintf(SE, " %d %.3f", v, Xv);
|
240
|
+
ExtendSiftEntry(SE);
|
241
|
+
}
|
242
|
+
}
|
243
|
+
ExtendSiftEntry(" 0");
|
244
|
+
}
|
245
|
+
|
246
|
+
|
247
|
+
|
248
|
+
void SaveContinCluster(float Mean, float SD, CaseCount Cases,
|
249
|
+
float LFrac, float LLim, float HFrac, float HLim)
|
250
|
+
/* ----------------- */
|
251
|
+
{
|
252
|
+
char SE[100];
|
253
|
+
|
254
|
+
SaveCondition();
|
255
|
+
|
256
|
+
sprintf(SE, "22 %d %g %g %g %.8g %g %.8g",
|
257
|
+
Cases, Mean, SD, LFrac, LLim, HFrac, HLim);
|
258
|
+
ExtendSiftEntry(SE);
|
259
|
+
}
|
260
|
+
|
261
|
+
|
262
|
+
|
263
|
+
/*************************************************************************/
|
264
|
+
/* */
|
265
|
+
/* Save attribute information */
|
266
|
+
/* */
|
267
|
+
/*************************************************************************/
|
268
|
+
|
269
|
+
|
270
|
+
void SaveNames()
|
271
|
+
/* --------- */
|
272
|
+
{
|
273
|
+
Attribute Att;
|
274
|
+
DiscrValue v;
|
275
|
+
int DN, Op;
|
276
|
+
|
277
|
+
fprintf(Sf, "atts=\"%d\"\n", MaxAtt);
|
278
|
+
|
279
|
+
ForEach(Att, 1, MaxAtt)
|
280
|
+
{
|
281
|
+
AsciiOut("att=", AttName[Att]);
|
282
|
+
fprintf(Sf, " sstat=\"%d\"", SpecialStatus[Att]);
|
283
|
+
|
284
|
+
if ( AttDef[Att] )
|
285
|
+
{
|
286
|
+
/* Dump definition */
|
287
|
+
|
288
|
+
fprintf(Sf, " def");
|
289
|
+
for ( DN = 0 ; ; DN++ )
|
290
|
+
{
|
291
|
+
Op = DefOp(AttDef[Att][DN]);
|
292
|
+
|
293
|
+
fprintf(Sf, "%c\"%d\"", ( DN ? ',' : '=' ), Op);
|
294
|
+
if ( Op == OP_ATT )
|
295
|
+
{
|
296
|
+
fprintf(Sf, ":\"%d\"",
|
297
|
+
(int) (long) DefSVal(AttDef[Att][DN]));
|
298
|
+
}
|
299
|
+
else
|
300
|
+
if ( Op == OP_STR )
|
301
|
+
{
|
302
|
+
AsciiOut(":", DefSVal(AttDef[Att][DN]));
|
303
|
+
}
|
304
|
+
else
|
305
|
+
{
|
306
|
+
fprintf(Sf, ":\"%g\"", DefNVal(AttDef[Att][DN]));
|
307
|
+
}
|
308
|
+
|
309
|
+
if ( Op == OP_END ) break;
|
310
|
+
}
|
311
|
+
}
|
312
|
+
|
313
|
+
if ( MaxAttVal[Att] > 0 )
|
314
|
+
{
|
315
|
+
AsciiOut(" elts=", AttValName[Att][2]); /* skip N/A */
|
316
|
+
|
317
|
+
ForEach(v, 3, MaxAttVal[Att])
|
318
|
+
{
|
319
|
+
AsciiOut(",", AttValName[Att][v]);
|
320
|
+
}
|
321
|
+
}
|
322
|
+
|
323
|
+
if ( Prec[Att] > 0 )
|
324
|
+
{
|
325
|
+
fprintf(Sf, " prec=\"%d\"", Prec[Att]);
|
326
|
+
}
|
327
|
+
|
328
|
+
fprintf(Sf, "\n");
|
329
|
+
}
|
330
|
+
|
331
|
+
if ( LabelAtt )
|
332
|
+
{
|
333
|
+
AsciiOut("label=", AttName[LabelAtt]);
|
334
|
+
fprintf(Sf, "\n");
|
335
|
+
}
|
336
|
+
}
|
337
|
+
|
338
|
+
|
339
|
+
|
340
|
+
/*************************************************************************/
|
341
|
+
/* */
|
342
|
+
/* Write ASCII string with prefix, escaping any quotes */
|
343
|
+
/* */
|
344
|
+
/*************************************************************************/
|
345
|
+
|
346
|
+
|
347
|
+
void AsciiOut(String Pre, String S)
|
348
|
+
/* -------- */
|
349
|
+
{
|
350
|
+
fprintf(Sf, "%s\"", Pre);
|
351
|
+
while ( *S )
|
352
|
+
{
|
353
|
+
if ( *S == '"' || *S == '\\' ) fputc('\\', Sf);
|
354
|
+
fputc(*S++, Sf);
|
355
|
+
}
|
356
|
+
fputc('"', Sf);
|
357
|
+
}
|
358
|
+
#endif
|
359
|
+
|
360
|
+
|
361
|
+
|
362
|
+
/*************************************************************************/
|
363
|
+
/* */
|
364
|
+
/* Read header information */
|
365
|
+
/* */
|
366
|
+
/*************************************************************************/
|
367
|
+
|
368
|
+
|
369
|
+
void ReadFilePrefix(String Extension)
|
370
|
+
/* -------------- */
|
371
|
+
{
|
372
|
+
Attribute Att=0;
|
373
|
+
DiscrValue v;
|
374
|
+
char *p, Dummy;
|
375
|
+
int Year, Month, Day, X, Elts, Op, DN, DefSize;
|
376
|
+
float A;
|
377
|
+
extern AttValue _UNK, _NA;
|
378
|
+
|
379
|
+
if ( ! (Sf = GetFile(Extension, "r")) ) Error(NOFILE, Fn, "");
|
380
|
+
|
381
|
+
while ( true )
|
382
|
+
{
|
383
|
+
switch ( ReadProp(&Dummy) )
|
384
|
+
{
|
385
|
+
case ERRORP:
|
386
|
+
Error(BADSIFT, PropName, "");
|
387
|
+
return;
|
388
|
+
|
389
|
+
case IDP:
|
390
|
+
/* Recover year run and set base date for timestamps */
|
391
|
+
|
392
|
+
if ( sscanf(PropVal + strlen(PropVal) - 11,
|
393
|
+
"%d-%d-%d\"", &Year, &Month, &Day) == 3 )
|
394
|
+
{
|
395
|
+
SetTSBase(Year);
|
396
|
+
}
|
397
|
+
break;
|
398
|
+
|
399
|
+
case ATTSP:
|
400
|
+
Unquoted = RemoveQuotes(PropVal);
|
401
|
+
if ( sscanf(Unquoted, "%d", &MaxAtt) != 1 )
|
402
|
+
{
|
403
|
+
Error(BADSIFT, "atts", "");
|
404
|
+
}
|
405
|
+
|
406
|
+
AttName = Alloc(MaxAtt+1, String);
|
407
|
+
SpecialStatus = AllocZero(MaxAtt+1, char);
|
408
|
+
AttDef = AllocZero(MaxAtt+1, Definition);
|
409
|
+
AttValName = Alloc(MaxAtt+1, String *);
|
410
|
+
MaxAttVal = AllocZero(MaxAtt+1, int);
|
411
|
+
Prec = Alloc(MaxAtt+1, unsigned char);
|
412
|
+
UseLogs = AllocZero(MaxAtt+1, Boolean);
|
413
|
+
LowTail = Alloc(MaxAtt+1, float);
|
414
|
+
HighTail = Alloc(MaxAtt+1, float);
|
415
|
+
|
416
|
+
Att = 0;
|
417
|
+
break;
|
418
|
+
|
419
|
+
case ATTP:
|
420
|
+
Att++;
|
421
|
+
if ( Att > MaxAtt )
|
422
|
+
{
|
423
|
+
Error(BADSIFT, "att", "");
|
424
|
+
}
|
425
|
+
|
426
|
+
Unquoted = RemoveQuotes(PropVal);
|
427
|
+
AttName[Att] = strdup(Unquoted);
|
428
|
+
|
429
|
+
LowTail[Att] = -1E38;
|
430
|
+
HighTail[Att] = 1E38;
|
431
|
+
break;
|
432
|
+
|
433
|
+
case SSTATP:
|
434
|
+
Unquoted = RemoveQuotes(PropVal);
|
435
|
+
if ( sscanf(Unquoted, "%d", &X) != 1 )
|
436
|
+
{
|
437
|
+
Error(BADSIFT, "sstat", "");
|
438
|
+
}
|
439
|
+
SpecialStatus[Att] = X;
|
440
|
+
break;
|
441
|
+
|
442
|
+
case ELTSP:
|
443
|
+
Elts = 100;
|
444
|
+
AttValName[Att] = Alloc(Elts, String);
|
445
|
+
|
446
|
+
MaxAttVal[Att] = 1;
|
447
|
+
AttValName[Att][1] = strdup("N/A");
|
448
|
+
|
449
|
+
for ( p = PropVal ; *p ; )
|
450
|
+
{
|
451
|
+
p = RemoveQuotes(p);
|
452
|
+
v = ++MaxAttVal[Att];
|
453
|
+
|
454
|
+
if ( v+2 >= Elts )
|
455
|
+
{
|
456
|
+
Elts += 100;
|
457
|
+
Realloc(AttValName[Att], Elts, String);
|
458
|
+
}
|
459
|
+
|
460
|
+
AttValName[Att][v] = strdup(p);
|
461
|
+
|
462
|
+
for ( p += strlen(p) ; *p != '"' ; p++ )
|
463
|
+
;
|
464
|
+
p++;
|
465
|
+
if ( *p == ',' ) p++;
|
466
|
+
}
|
467
|
+
break;
|
468
|
+
|
469
|
+
case PRECP:
|
470
|
+
Unquoted = RemoveQuotes(PropVal);
|
471
|
+
if ( sscanf(Unquoted, "%d", &X) != 1 )
|
472
|
+
{
|
473
|
+
Error(BADSIFT, "prec", "");
|
474
|
+
}
|
475
|
+
Prec[Att] = X;
|
476
|
+
break;
|
477
|
+
|
478
|
+
case LABELP:
|
479
|
+
Unquoted = RemoveQuotes(PropVal);
|
480
|
+
LabelAtt = Which(Unquoted, AttName, 1, MaxAtt);
|
481
|
+
break;
|
482
|
+
|
483
|
+
case DEFP:
|
484
|
+
/* Make sure _UNK and _NA are set */
|
485
|
+
|
486
|
+
_UNK._discr_val = UNKNOWN;
|
487
|
+
_NA._discr_val = NA;
|
488
|
+
|
489
|
+
/* Allocate initial space for definition */
|
490
|
+
|
491
|
+
AttDef[Att] = AllocZero(DefSize = 100, DefElt);
|
492
|
+
DN = 0;
|
493
|
+
|
494
|
+
/* Read definition operators */
|
495
|
+
|
496
|
+
for ( p = PropVal ; *p ; )
|
497
|
+
{
|
498
|
+
/* Check that space is available */
|
499
|
+
|
500
|
+
if ( DN >= DefSize )
|
501
|
+
{
|
502
|
+
DefSize += 100;
|
503
|
+
Realloc(AttDef[Att], DefSize, DefElt);
|
504
|
+
}
|
505
|
+
|
506
|
+
/* Read opcode */
|
507
|
+
|
508
|
+
p = RemoveQuotes(p);
|
509
|
+
if ( sscanf(p, "%d", &Op) != 1 )
|
510
|
+
{
|
511
|
+
Error(BADSIFT, "def", "");
|
512
|
+
}
|
513
|
+
DefOp(AttDef[Att][DN]) = Op;
|
514
|
+
|
515
|
+
/* Move to start of operand */
|
516
|
+
|
517
|
+
for ( p += strlen(p) ; *p != '"' ; p++ )
|
518
|
+
;
|
519
|
+
p++;
|
520
|
+
if ( *p != ':' )
|
521
|
+
{
|
522
|
+
Error(BADSIFT, "def", "");
|
523
|
+
}
|
524
|
+
p++;
|
525
|
+
|
526
|
+
/* Read operand -- depends on opcode */
|
527
|
+
|
528
|
+
p = RemoveQuotes(p);
|
529
|
+
|
530
|
+
if ( Op == OP_ATT )
|
531
|
+
{
|
532
|
+
if ( sscanf(p, "%d", &X) != 1 )
|
533
|
+
{
|
534
|
+
Error(BADSIFT, "def", "");
|
535
|
+
}
|
536
|
+
DefSVal(AttDef[Att][DN]) = (void *) X;
|
537
|
+
}
|
538
|
+
else
|
539
|
+
if ( Op == OP_STR )
|
540
|
+
{
|
541
|
+
DefSVal(AttDef[Att][DN]) = strdup(p);
|
542
|
+
}
|
543
|
+
else
|
544
|
+
{
|
545
|
+
if ( sscanf(p, "%g", &A) != 1 )
|
546
|
+
{
|
547
|
+
Error(BADSIFT, "def", "");
|
548
|
+
}
|
549
|
+
DefNVal(AttDef[Att][DN]) = A;
|
550
|
+
}
|
551
|
+
|
552
|
+
/* Get ready for next entry */
|
553
|
+
|
554
|
+
DN++;
|
555
|
+
|
556
|
+
for ( p += strlen(p) ; *p != '"' ; p++ )
|
557
|
+
;
|
558
|
+
p++;
|
559
|
+
if ( *p == ',' ) p++;
|
560
|
+
}
|
561
|
+
break;
|
562
|
+
|
563
|
+
case MINABNORMP:
|
564
|
+
Unquoted = RemoveQuotes(PropVal);
|
565
|
+
if ( sscanf(Unquoted, "%g", &MINABNORM) != 1 )
|
566
|
+
{
|
567
|
+
Error(BADSIFT, "minabnorm", "");
|
568
|
+
}
|
569
|
+
return;
|
570
|
+
}
|
571
|
+
}
|
572
|
+
}
|
573
|
+
|
574
|
+
|
575
|
+
|
576
|
+
/*************************************************************************/
|
577
|
+
/* */
|
578
|
+
/* ASCII reading utilities */
|
579
|
+
/* */
|
580
|
+
/*************************************************************************/
|
581
|
+
|
582
|
+
|
583
|
+
int ReadProp(char *Delim)
|
584
|
+
/* -------- */
|
585
|
+
{
|
586
|
+
int c, i;
|
587
|
+
char *p;
|
588
|
+
Boolean Quote=false;
|
589
|
+
|
590
|
+
for ( p = PropName ; (c = fgetc(Sf)) != '=' ; )
|
591
|
+
{
|
592
|
+
if ( p - PropName >= 19 || c == EOF )
|
593
|
+
{
|
594
|
+
Error(BADSIFT, "EOF", "");
|
595
|
+
PropName[0] = PropVal[0] = *Delim = '\00';
|
596
|
+
return 0;
|
597
|
+
}
|
598
|
+
*p++ = c;
|
599
|
+
}
|
600
|
+
*p = '\00';
|
601
|
+
|
602
|
+
for ( p = PropVal ; ((c = fgetc(Sf)) != ' ' && c != '\n') || Quote ; )
|
603
|
+
{
|
604
|
+
if ( c == EOF )
|
605
|
+
{
|
606
|
+
Error(BADSIFT, "EOF", "");
|
607
|
+
PropName[0] = PropVal[0] = '\00';
|
608
|
+
return 0;
|
609
|
+
}
|
610
|
+
|
611
|
+
if ( (i = p - PropVal) >= PropValSize )
|
612
|
+
{
|
613
|
+
PropValSize += 10000;
|
614
|
+
Realloc(PropVal, PropValSize + 3, char);
|
615
|
+
p = PropVal + i;
|
616
|
+
}
|
617
|
+
|
618
|
+
*p++ = c;
|
619
|
+
if ( c == '\\' )
|
620
|
+
{
|
621
|
+
*p++ = fgetc(Sf);
|
622
|
+
}
|
623
|
+
else
|
624
|
+
if ( c == '"' )
|
625
|
+
{
|
626
|
+
Quote = ! Quote;
|
627
|
+
}
|
628
|
+
}
|
629
|
+
*p = '\00';
|
630
|
+
*Delim = c;
|
631
|
+
|
632
|
+
return Which(PropName, Prop, 1, PROPS);
|
633
|
+
}
|
634
|
+
|
635
|
+
|
636
|
+
|
637
|
+
String RemoveQuotes(String S)
|
638
|
+
/* ------------ */
|
639
|
+
{
|
640
|
+
char *p, *Start;
|
641
|
+
|
642
|
+
p = Start = S;
|
643
|
+
|
644
|
+
for ( S++ ; *S != '"' ; S++ )
|
645
|
+
{
|
646
|
+
if ( *S == '\\' ) S++;
|
647
|
+
*p++ = *S;
|
648
|
+
*S = '-';
|
649
|
+
}
|
650
|
+
*p = '\00';
|
651
|
+
|
652
|
+
return Start;
|
653
|
+
}
|
654
|
+
|
655
|
+
|
656
|
+
|
657
|
+
/*************************************************************************/
|
658
|
+
/* */
|
659
|
+
/* Add more text to a sift entry */
|
660
|
+
/* */
|
661
|
+
/*************************************************************************/
|
662
|
+
|
663
|
+
|
664
|
+
void ExtendSiftEntry(String S)
|
665
|
+
/* --------------- */
|
666
|
+
{
|
667
|
+
int Len;
|
668
|
+
|
669
|
+
/* Make sure there is enough room */
|
670
|
+
|
671
|
+
if ( (Len = strlen(S)) >= GEnv.SiftSpace - GEnv.SiftSize )
|
672
|
+
{
|
673
|
+
GEnv.SiftSpace += 1000;
|
674
|
+
|
675
|
+
if ( GEnv.SiftEntry )
|
676
|
+
{
|
677
|
+
Realloc(GEnv.SiftEntry, GEnv.SiftSpace, char);
|
678
|
+
}
|
679
|
+
else
|
680
|
+
{
|
681
|
+
GEnv.SiftEntry = Alloc(GEnv.SiftSpace, char);
|
682
|
+
}
|
683
|
+
}
|
684
|
+
|
685
|
+
strcpy(GEnv.SiftEntry + GEnv.SiftSize, S);
|
686
|
+
GEnv.SiftSize += Len;
|
687
|
+
}
|