1
/*
2
 *=============================================================================
3
 *  flex based parser for DATCOM input cards.
4
 *
5
 *  Copyright (C) 2009  Anders Gidenstam (anders(at)gidenstam.org)
6
 *  Copyright (C) 2009  Ronald Jensen    (ron(at)jentronics.com)
7
 *
8
 *  This program is free software; you can redistribute it and/or modify
9
 *  it under the terms of the GNU General Public License as published by
10
 *  the Free Software Foundation; either version 3 of the License, or
11
 *  (at your option) any later version.
12
 *
13
 *  This program is distributed in the hope that it will be useful,
14
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 *  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
 *  along with this program; if not, write to the Free Software
20
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21
 *=============================================================================
22
 */
23
24
%{
25
    #include <stdio.h>
26
    #include <string.h>
27
    #include <math.h>
28
    #include "datcom-parser.h"
29
    extern int verbose;
30
31
    /* Internal global variables. */
32
    static AIRCRAFT* current_aircraft;
33
34
    static int current_namelist;
35
    #define NL_NONE    0
36
    #define NL_UNKNOWN 1
37
    #define NL_SYNTHS  2
38
    #define NL_BODY    3
39
    #define NL_WGPLNF  4
40
    #define NL_HTPLNF  5
41
    #define NL_VTPLNF  6
42
    #define NL_VFPLNF  7
43
    #define NL_WGSCHR  8
44
    #define NL_HTSCHR  9
45
    #define NL_VTSCHR  10
46
    #define NL_VFSCHR  11
47
    #define NL_PROPWR  12
48
    #define NL_SYMFLP  13
49
    #define NL_ASYFLP  14
50
    #define NL_OPTINS  15
51
    #define NL_MAX     16 /* Keep this entry last! */
52
53
    static int line_number;
54
55
    /* For variables and array variables. */
56
    static double* next_double;
57
    static int     num_doubles;
58
59
    static int*    next_int;
60
    static int*    next_bool;
61
62
    static const char* NL_NAME[] = {
63
                                       "",
64
                                       "",
65
                                       "$SYNTHS",
66
                                       "$BODY",
67
                                       "$WGPLNF",
68
                                       "$HTPLNF",
69
                                       "$VTPLNF",
70
                                       "$VFPLNF",
71
                                       "$WGSCHR",
72
                                       "$HTSCHR",
73
                                       "$VTSCHR",
74
                                       "$VFSCHR",
75
                                       "$PROPWR",
76
                                       "$SYMFLP",
77
                                       "$ASYFLP",
78
                                       "$OPTINS",
79
                                   };
80
81
    /* Internal functions. */
82
    static void InitializeParser(AIRCRAFT* aircraft);
83
    static void Fail();
84
    static void BeginNameList(char* name);
85
    static void EndNameList();
86
    static void ReadVariable(char* var);
87
    static void ReadNumber(char* str); /* Reads a double or an int */ 
88
89
    static void OPTINSReadVariable(char* var);
90
    static void SYNTHSReadVariable(char* var);
91
    static void BODYReadVariable(char* var);
92
    static void PLNFReadVariable(char* var, struct WGPLNF* surface);
93
    static void SCHRReadVariable(char* var, DATCOM_AIRFOIL* airfoil);
94
    static void PROPWRReadVariable(char* var);
95
96
    static void NACARead(char* str);
97
    /* Added by Bill Galbraith 10-13-10 */
98
    static void ClearLineRead();
99
    static void AppendToLineRead(char* str);
100
    char LineRead[300];
101
%}
102
103
/* This tells flex to read only one input file */
104
%option noyywrap
105
106
/* Parser conditions/"states" */
107
%s namelist
108
109
DIGIT           [0-9]
110
ALPHA           [a-zA-Z]
111
ALPHANUM        [A-Za-z0-9]
112
ID              [A-Z][A-Z0-9]*
113
WS              [ \t]
114
EOL             "\n"|"\n\r"|"\r\n"
115
NEOL            [^\n\r]
116
117
/* Bill Galbraith  10-12-10
118
   Redefined what a DOUBLE was, to :
119
      digit(s), a decimal point, and digit(s)
120
      digit(s) and a decimal point
121
      a decimal point and digit(s)
122
   and of which may or may not have a leading minus sign and
123
   trailing exponent, which is made up of an optional minus sign
124
   and digit(s)
125
   * IMPORTANT NOTE * The DOUBLE is also defined as ending with a comma.
126
127
   Old definition
128
DOUBLE          "-"?{DIGIT}*"."{DIGIT}*("E""-"?{DIGIT}+)?   */
129
130
/* This works, except it doesn't account for not having
131
   the numbers separated by commas. If you fix this, also have BOOLEAN
132
   separated by commas.
133
*/
134
DOUBLE          ("-"?{DIGIT}+"."{DIGIT}+("E""-"?{DIGIT}+)?|"-"?{DIGIT}+"."("E""-"?{DIGIT}+)?|"-"?"."{DIGIT}+("E""-"?{DIGIT}+)?)
135
136
BOOL            \.TRUE\.|\.FALSE\.
137
COMMAND         ^(PART|DERIV|DUMP|DAMP|SAVE|NEXT|CASEID|BUILD|PLOT|TRIM)
138
DIMENSION       ^(DIM)
139
NAMELIST        "$"{ID}
140
VAR             {ID}({WS}*"=")
141
ARRVAR          {ID}"(1)"{WS}*"="
142
NACAAIRFOIL     ^"NACA"({WS}|"-"){NEOL}*{LENDCOMMENT}?
143
LINECOMMENT     ^("*"|"#"){NEOL}*
144
LENDCOMMENT     "!"{NEOL}*
145
146
/*******************************************************************************
147
 * Rules
148
 */
149
%%
150
151
<namelist>{DOUBLE} {
152
    if (verbose > 2) fprintf(stderr,"datcom-parser:    DOUBLE: %s = %g\n", yytext, atof(yytext));
153
    /* Bill Galbraith 10-13-10  This is a more accurate output */
154
    /* Ron Jensen 10-13-10 The conversion is done with atof() so perhaps both are interesting */
155
    //fprintf(stderr,"    DOUBLE: %s\n", yytext);
156
    ReadNumber(yytext);
157
    AppendToLineRead(yytext);
158
}
159
160
<namelist>{BOOL} {
161
    if (verbose > 2) fprintf(stderr,"datcom-parser:    BOOL: %s\n", yytext);
162
    ReadNumber(yytext);
163
    AppendToLineRead(yytext);
164
}
165
166
<INITIAL>{NAMELIST} {
167
    if (verbose > 2) fprintf(stderr,"datcom-parser:NAMELIST: %s\n", yytext);
168
    BEGIN(namelist);
169
    BeginNameList(yytext);
170
    AppendToLineRead(yytext);
171
}
172
173
<namelist>"$" {
174
    if (verbose > 2) fprintf(stderr,"datcom-parser:END OF NAMELIST\n");
175
    BEGIN(INITIAL);
176
    EndNameList();
177
    AppendToLineRead(yytext);
178
}
179
180
<namelist>{ARRVAR} {
181
    char* e;
182
    AppendToLineRead(yytext);
183
    /* Strip trailing garbage. I hope this is safe.. */
184
    e = strchr(yytext, '(');
185
    if (e != NULL) {
186
        *e = '\0';
187
    }
188
    if (verbose > 2) fprintf(stderr,"datcom-parser:  ARRAYVARIABLE: %s\n", yytext);
189
190
    ReadVariable(yytext);
191
}
192
193
<namelist>{VAR} {
194
    char* s;
195
    char* e;
196
197
    /* Strip trailing garbage. I hope this is safe.. */
198
    s = strchr(yytext, ' ');
199
    e = strchr(yytext, '=');
200
    e = (e != NULL) ? e : s;
201
    s = (s != NULL) ? s : e;
202
    e = (e < s) ? e : s;
203
    if (e != NULL) {
204
        *e = '\0';
205
    }
206
    AppendToLineRead(yytext);
207
    if (verbose > 2) fprintf(stderr,"datcom-parser:  VARIABLE: %s\n", yytext);
208
209
    ReadVariable(yytext);
210
}
211
212
{NACAAIRFOIL} {
213
    if (verbose > 2) fprintf(stderr,"datcom-parser:AIRFOIL: %s\n", yytext);
214
    NACARead(yytext);
215
    ClearLineRead();
216
}
217
218
{COMMAND}{NEOL}* {
219
	if (verbose > 2) fprintf(stderr,"datcom-parser:Command: %s\n", yytext);
220
221
    /* Drop uninteresting commands */
222
    ClearLineRead();
223
}
224
225
{DIMENSION}{NEOL}* {
226
	if (verbose) fprintf(stderr,"datcom-parser:Dimension: %s\n", yytext);
227
228
    /* Drop uninteresting commands */
229
    ClearLineRead();
230
}
231
232
{LINECOMMENT} {
233
    /* Drop comment lines */
234
   ClearLineRead();
235
}
236
237
{LENDCOMMENT} {
238
    /* Drop comment lines */
239
    ClearLineRead();
240
}
241
242
{EOL} {
243
    line_number++;
244
   ClearLineRead();
245
}
246
247
"," {
248
    /* Eat ',' */
249
    AppendToLineRead(yytext);
250
}
251
252
{WS} {
253
    /* Eat up whitespace */
254
}
255
256
. {
257
    Fail();
258
}
259
260
%%
261
/*******************************************************************************
262
 * Verbatim code section
263
 */
264
265
/* Main entry point. */
266
void ReadDatcom(char* filename, AIRCRAFT* aircraft)
267
{
268
    yyin = fopen(filename, "r");
269
270
    if(!yyin){
271
      fprintf(stderr,"Failed to open input file %s\n", filename);
272
      exit(EXIT_FAILURE);
273
    }
274
275
    InitializeParser(aircraft);
276
    yylex();
277
    fclose(yyin);
278
}
279
280
static void InitializeParser(AIRCRAFT* aircraft)
281
{
282
    /* Bill Galbraith  10-12-10
283
       Changed the initial value from 0 to 1, so that the line numbers
284
       output actually matches that in the file. */
285
    
286
    line_number = 1;
287
288
    current_aircraft = aircraft;
289
    current_namelist = NL_NONE;
290
    next_double      = NULL;
291
    num_doubles      = 0;
292
    next_int         = NULL;
293
294
    memset(current_aircraft, 0, sizeof(AIRCRAFT));
295
    current_aircraft->optins.ROUGFC=-1; // using this as the unset value in modeler.c GetShiny()
296
}
297
298
static void Fail()
299
{
300
    if (verbose > 0) fprintf(stderr, "datcom-parser: Error: Unrecognized or misplaced character '%s' in line %d\n",
301
            yytext, line_number);
302
    fprintf(stderr, "Errant line up to the error is:\n%s\n", LineRead );
303
    exit(-1);
304
}
305
306
static void BeginNameList(char* name)
307
{
308
    int i;
309
    if (current_namelist != NL_NONE) {
310
        if (verbose > 0) fprintf(stderr,
311
               "datcom-parser: Unterminated NAMELIST in line %d\n",
312
                line_number);
313
        exit(-1);
314
    }
315
    current_namelist = NL_UNKNOWN;
316
    for (i = 0; i < NL_MAX; i++) {
317
        if (strcmp(name, NL_NAME[i]) == 0) {
318
            current_namelist = i;
319
        }
320
    }
321
322
    if (current_namelist == NL_UNKNOWN) {
323
        if (verbose > 1) fprintf(stderr,
324
               "datcom-parser: Unknown NAMELIST %s in line %d\n",
325
                name,
326
                line_number);
327
    }
328
 }
329
330
static void EndNameList()
331
{
332
    if (current_namelist == NL_NONE) {
333
        if (verbose > 0) fprintf(stderr,
334
                "datcom-parser: Unbegun NAMELIST terminated in line %d\n",
335
                line_number);
336
        exit(-1);
337
    }
338
    current_namelist = NL_NONE;
339
}
340
341
static void ReadVariable(char* var)
342
{
343
    if(verbose > 3)  
344
    {
345
        switch (current_namelist) {
346
        case NL_NONE:
347
            fprintf(stderr,"datcom-parser: NL_NONE\n");
348
            break;
349
        case NL_UNKNOWN: // This case will print elsewhere
350
//            fprintf(stderr,"datcom-parser: NL_UNKNOWN\n");
351
            break;
352
        default:
353
            if(current_namelist < NL_MAX) fprintf(stderr,"datcom-parser: %s\n", NL_NAME[current_namelist]);
354
        }
355
    }
356
    switch (current_namelist) {
357
    case NL_NONE:
358
        if (verbose > 0) fputs("datcom-parser: Variable outside of NAMELIST", stderr);
359
        exit(-1);
360
        break;
361
    case NL_SYNTHS:
362
        SYNTHSReadVariable(var);
363
        break;
364
    case NL_BODY:
365
        BODYReadVariable(var);
366
        break;
367
    case NL_WGPLNF:
368
        PLNFReadVariable(var, &current_aircraft->wing);
369
        break;
370
    case NL_HTPLNF:
371
        PLNFReadVariable(var, &current_aircraft->htail);
372
        break;
373
    case NL_VTPLNF:
374
        PLNFReadVariable(var, &current_aircraft->vtail);
375
        break;
376
    case NL_VFPLNF:
377
        PLNFReadVariable(var, &current_aircraft->vfin);
378
        break;
379
    case NL_WGSCHR:
380
        SCHRReadVariable(var, &current_aircraft->wingfoil);
381
        break;
382
    case NL_HTSCHR:
383
        SCHRReadVariable(var, &current_aircraft->htailfoil);
384
        break;
385
    case NL_VTSCHR:
386
        SCHRReadVariable(var, &current_aircraft->vtailfoil);
387
        break;
388
    case NL_VFSCHR:
389
        SCHRReadVariable(var, &current_aircraft->vfinfoil);
390
        break;
391
    case NL_PROPWR:
392
        PROPWRReadVariable(var);
393
        break;
394
    case NL_SYMFLP:
395
// FIXME: Do Something!
396
        break;
397
    case NL_ASYFLP:
398
// FIXME: Do Something!
399
        break;
400
    case NL_OPTINS:
401
        OPTINSReadVariable(var);
402
        break;
403
    default:
404
        break;
405
    }
406
}
407
408
static void ReadNumber(char* str)
409
{
410
    if (num_doubles-- && next_double != NULL) {
411
        *next_double = atof(yytext); /* Add error detection here! */
412
        next_double = (num_doubles > 0) ? next_double + 1 : NULL;
413
    } else if (next_int) {
414
        *next_int = (int)atof(yytext); /* Add error detection here! */
415
        next_int = NULL;
416
    } else if (next_bool) {
417
        if (strcmp(yytext, ".TRUE.") == 0) {
418
            *next_bool = 1;
419
        } else {
420
            *next_bool = 0;
421
        }
422
        next_bool=NULL;
423
    }
424
}
425
426
static void PROPWRReadVariable(char* var)
427
{
428
    num_doubles = 1;
429
    if (strcmp(var, "AIETLP") == 0) {
430
        next_double = &current_aircraft->propwr.AIETLP;
431
    } else if (strcmp(var, "NENGSP") == 0) {
432
        next_double = &current_aircraft->propwr.NENGSP;
433
    } else if (strcmp(var, "THSTCP") == 0) {
434
        next_double = &current_aircraft->propwr.THSTCP;
435
    } else if (strcmp(var, "PHALOC") == 0) {
436
        next_double = &current_aircraft->propwr.PHALOC;
437
    } else if (strcmp(var, "PHVLOC") == 0) {
438
        next_double = &current_aircraft->propwr.PHVLOC;
439
    } else if (strcmp(var, "PRPRAD") == 0) {
440
        next_double = &current_aircraft->propwr.PRPRAD;
441
    } else if (strcmp(var, "BWAPR3") == 0) {
442
        next_double = &current_aircraft->propwr.BWAPR3;
443
    } else if (strcmp(var, "BWAPR6") == 0) {
444
        next_double = &current_aircraft->propwr.BWAPR6;
445
    } else if (strcmp(var, "BWAPR9") == 0) {
446
        next_double = &current_aircraft->propwr.BWAPR9;
447
    } else if (strcmp(var, "NOPBPE") == 0) {
448
        next_double = &current_aircraft->propwr.NOPBPE;
449
    } else if (strcmp(var, "BAPR75") == 0) {
450
        next_double = &current_aircraft->propwr.BAPR75;
451
    } else if (strcmp(var, "YP") == 0) {
452
        next_double = &current_aircraft->propwr.YP;
453
    } else if (strcmp(var, "CROT") == 0) {
454
        num_doubles = 0;
455
        next_int = &current_aircraft->propwr.CROT;
456
    } else {
457
       if (verbose > 1) fprintf(stderr,
458
                "datcom-parser: Unknown variable %s in PROPWR NAMELIST close to line %d\n",
459
                var, line_number);
460
    }
461
}
462
463
464
static void OPTINSReadVariable(char* var)
465
{
466
    num_doubles = 1;
467
    if (strcmp(var, "ROUGFC") == 0) {
468
        next_double = &current_aircraft->optins.ROUGFC;
469
    } else if (strcmp(var, "SREF") == 0) {
470
        next_double = &current_aircraft->optins.SREF;
471
    } else if (strcmp(var, "CBARR") == 0) {
472
        next_double = &current_aircraft->optins.CBARR;
473
    } else if (strcmp(var, "BLREF") == 0) {
474
        next_double = &current_aircraft->optins.BLREF;
475
    } else {
476
       if (verbose > 1) fprintf(stderr,
477
                "datcom-parser: Unknown variable %s in OPTIN NAMELIST close to line %d\n",
478
                var, line_number);
479
    }
480
} 
481
482
static void SYNTHSReadVariable(char* var)
483
{
484
    /*printf("SYNTHS: %s\n", var);*/
485
    num_doubles = 1;
486
    if (strcmp(var, "XCG") == 0) {
487
        next_double = &current_aircraft->synths.XCG;
488
    } else if (strcmp(var, "ZCG") == 0) {
489
        next_double = &current_aircraft->synths.ZCG;
490
    } else if (strcmp(var, "XW") == 0) {
491
        next_double = &current_aircraft->synths.XW;
492
    } else if (strcmp(var, "ZW") == 0) {
493
        next_double = &current_aircraft->synths.ZW;
494
    } else if (strcmp(var, "ALIW") == 0) {
495
        next_double = &current_aircraft->synths.ALIW;
496
    } else if (strcmp(var, "XH") == 0) {
497
        next_double = &current_aircraft->synths.XH;
498
    } else if (strcmp(var, "ZH") == 0) {
499
        next_double = &current_aircraft->synths.ZH;
500
    } else if (strcmp(var, "ALIH") == 0) {
501
        next_double = &current_aircraft->synths.ALIH;
502
    } else if (strcmp(var, "XV") == 0) {
503
        next_double = &current_aircraft->synths.XV;
504
    } else if (strcmp(var, "ZV") == 0) {
505
        next_double = &current_aircraft->synths.ZV;
506
    } else if (strcmp(var, "XVF") == 0) {
507
        next_double = &current_aircraft->synths.XVF;
508
    } else if (strcmp(var, "ZVF") == 0) {
509
        next_double = &current_aircraft->synths.ZVF;
510
    } else if (strcmp(var, "SCALE") == 0) {
511
        next_double = &current_aircraft->synths.SCALE;
512
    } else if (strcmp(var, "HINAX") == 0) {
513
        next_double = &current_aircraft->synths.HINAX;
514
    } else if (strcmp(var, "VERTUP") == 0) {
515
        num_doubles = 0;
516
        next_int = NULL;
517
        next_bool = &current_aircraft->synths.VERTUP;
518
    } else {
519
       if (verbose > 1) fprintf(stderr,
520
                "datcom-parser: Unknown variable %s in SYNTHS NAMELIST in line %d\n",
521
                var, line_number);
522
    }
523
}
524
525
static void BODYReadVariable(char* var)
526
{
527
    if (strcmp(var, "NX") == 0) {
528
        next_int = &current_aircraft->body.NX;
529
    } else if (strcmp(var, "X") == 0) {
530
        num_doubles = current_aircraft->body.NX;
531
        next_double = &current_aircraft->body.X[0];
532
    } else if (strcmp(var, "S") == 0) {
533
        num_doubles = current_aircraft->body.NX;
534
        next_double = &current_aircraft->body.S[0];
535
    } else if (strcmp(var, "P") == 0) {
536
        num_doubles = current_aircraft->body.NX;
537
        next_double = &current_aircraft->body.P[0];
538
    } else if (strcmp(var, "R") == 0) {
539
        num_doubles = current_aircraft->body.NX;
540
        next_double = &current_aircraft->body.R[0];
541
    } else if (strcmp(var, "ZU") == 0) {
542
        num_doubles = current_aircraft->body.NX;
543
        next_double = &current_aircraft->body.ZU[0];
544
    } else if (strcmp(var, "ZL") == 0) {
545
        num_doubles = current_aircraft->body.NX;
546
        next_double = &current_aircraft->body.ZL[0];
547
    } else if (strcmp(var, "BNOSE") == 0) {
548
        num_doubles = 1;
549
        next_double = &current_aircraft->body.BNOSE;
550
    } else if (strcmp(var, "BTAIL") == 0) {
551
        num_doubles = 1;
552
        next_double = &current_aircraft->body.BTAIL;
553
    } else if (strcmp(var, "BLN") == 0) {
554
        num_doubles = 1;
555
        next_double = &current_aircraft->body.BLN;
556
    } else if (strcmp(var, "BLA") == 0) {
557
        num_doubles = 1;
558
        next_double = &current_aircraft->body.BLA;
559
    } else if (strcmp(var, "DS") == 0) {
560
        num_doubles = 1;
561
        next_double = &current_aircraft->body.DS;
562
    } else if (strcmp(var, "ITYPE") == 0) {
563
        num_doubles = 0;
564
        next_int = &current_aircraft->body.ITYPE;
565
    } else if (strcmp(var, "METHOD") == 0) {
566
        num_doubles = 0;
567
        next_int = &current_aircraft->body.METHOD;
568
    } else {
569
        if (verbose > 1) fprintf(stderr,
570
                "datcom-parser: Unknown variable %s in BODY NAMELIST in line %d\n",
571
                var, line_number);
572
    }
573
}
574
575
static void PLNFReadVariable(char* var, struct WGPLNF* surface)
576
{
577
    num_doubles = 1;
578
    if (strcmp(var, "CHRDR") == 0) {
579
        next_double = &surface->CHRDR;
580
    } else if (strcmp(var, "CHRDBP") == 0) {
581
        next_double = &surface->CHRDBP;
582
    } else if (strcmp(var, "CHRDTP") == 0) {
583
        next_double = &surface->CHRDTP;
584
    } else if (strcmp(var, "SSPN") == 0) {
585
        next_double = &surface->SSPN;
586
    } else if (strcmp(var, "SSPNE") == 0) {
587
        next_double = &surface->SSPNE;
588
    } else if (strcmp(var, "SSPNOP") == 0) {
589
        next_double = &surface->SSPNOP;
590
    } else if (strcmp(var, "SAVSI") == 0) {
591
        next_double = &surface->SAVSI;
592
    } else if (strcmp(var, "SAVSO") == 0) {
593
        next_double = &surface->SAVSO;
594
    } else if (strcmp(var, "CHSTAT") == 0) {
595
        next_double = &surface->CHSTAT;
596
    } else if (strcmp(var, "TWISTA") == 0) {
597
        next_double = &surface->TWISTA;
598
    } else if (strcmp(var, "SSPNDD") == 0) {
599
        next_double = &surface->SSPNDD;
600
    } else if (strcmp(var, "DHDADI") == 0) {
601
        next_double = &surface->DHDADI;
602
    } else if (strcmp(var, "DHDADO") == 0) {
603
        next_double = &surface->DHDADO;
604
    } else if (strcmp(var, "TYPE") == 0) {
605
        num_doubles = 0;
606
        next_int    = &surface->TYPE;
607
    } else {
608
       if (verbose > 1) fprintf(stderr,
609
                "datcom-parser: Unknown variable %s in PLNF NAMELIST around line %d\n",
610
                var, line_number);
611
    }
612
}
613
614
static void SCHRReadVariable(char* var, DATCOM_AIRFOIL *airfoil)
615
{
616
    if (strcmp(var, "TYPEIN") == 0) {
617
        next_int = &airfoil->TYPEIN;
618
    } else if (strcmp(var, "NPTS") == 0) {
619
        next_int = &airfoil->NPTS;
620
    } else if (strcmp(var, "XCORD") == 0) {
621
        num_doubles = airfoil->NPTS;
622
        airfoil->XCORD = calloc(num_doubles, sizeof(double));
623
        next_double = &airfoil->XCORD[0];
624
    } else if (strcmp(var, "YUPPER") == 0) {
625
        num_doubles = airfoil->NPTS;
626
        airfoil->YUPPER = calloc(num_doubles, sizeof(double));
627
        next_double = &airfoil->YUPPER[0];
628
    } else if (strcmp(var, "YLOWER") == 0) {
629
        num_doubles = airfoil->NPTS;
630
        airfoil->YLOWER = calloc(num_doubles, sizeof(double));
631
        next_double = &airfoil->YLOWER[0];
632
    } else {
633
       if (verbose > 1) fprintf(stderr,
634
                "datcom-parser: Unknown variable %s in SCHR NAMELIST in line %d\n",
635
                var, line_number);
636
    } 
637
}
638
639
static void NACARead(char* str)
640
{
641
    ClearLineRead();
642
    switch (str[5]) {
643
    case 'W':
644
        current_aircraft->wingfoil.NACA_DESCR =
645
            (char *)malloc(strlen(str) + 1);
646
        strcpy(current_aircraft->wingfoil.NACA_DESCR, str);
647
        break;
648
    case 'H':
649
        current_aircraft->htailfoil.NACA_DESCR =
650
            (char *)malloc(strlen(str) + 1);
651
        strcpy(current_aircraft->htailfoil.NACA_DESCR, str);
652
        break;
653
    case 'V':
654
        current_aircraft->vtailfoil.NACA_DESCR =
655
            (char *)malloc(strlen(str) + 1);
656
        strcpy(current_aircraft->vtailfoil.NACA_DESCR, str);
657
        break;
658
    case 'F':
659
        current_aircraft->vfinfoil.NACA_DESCR =
660
            (char *)malloc(strlen(str) + 1);
661
        strcpy(current_aircraft->vfinfoil.NACA_DESCR, str);
662
        break;
663
    default:
664
       if (verbose > 1) fprintf(stderr, "datcom-parser: Unknow surface in NACA airfoil %s in line %d\n",
665
                str, line_number);
666
        break;
667
    }
668
}
669
670
static void ClearLineRead()
671
{
672
    strcpy( LineRead,"" );
673
}
674
675
static void AppendToLineRead(char* str)
676
{
677
    strcat( LineRead, str );
678
    if ( strlen(LineRead) > 80 )
679
    {
680
       fprintf(stderr,"datcom-parser: Line is too long at line %d. Keep it under 80 characters\n%s\n", 
681
          line_number, LineRead );
682
//       exit(-1);
683
    }
684
}