4 * Copyright (C) 1993-1999 by Jochen Wiedmann and Marcin Orlowski
5 * Copyright (C) 2002-2017 FlexCat Open Source Team
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or (at
10 * your option) any later version.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "showfuncs.h"
25 #include "readprefs.h"
28 #include "createcat.h"
30 struct CDLine
*FirstCDLine
= NULL
; /* First catalog description line. */
31 char *HeaderName
= NULL
;
35 /* This scans the catalog description file.
36 Inputs: cdfile - name of the catalog description file
37 Result: TRUE if successful, FALSE otherwise */
39 int ScanCDFile(char *cdfile
)
42 struct CDLine
*cdline
, **cdptr
= &FirstCDLine
;
43 struct CatString
*cs
, **csptr
= &FirstCatString
;
52 if((fp
= fopen(cdfile
, "r")) == NULL
)
54 ShowErrorQuick(MSG_ERR_NOCATALOGDESCRIPTION
, cdfile
);
58 setvbuf(fp
, NULL
, _IOFBF
, buffer_size
);
60 // initialize "line" ahead of the loop
61 // the loop will bail out early for empty files
64 while(!feof(fp
) && (line
= newline
= ReadLine(fp
, TRUE
)) != NULL
)
66 if((cdline
= malloc(sizeof(*cdline
))) == NULL
)
72 cdptr
= &cdline
->Next
;
74 cdline
->Line
= line
= AllocString(newline
);
83 int CheckExtra
= TRUE
;
85 /* '#' in the first column of a line is the command introducer --
86 any number of # symbols, blank spaces and tabs afterwards are
87 skipped for compatibility with CatComp */
89 while(*line
== '#' || *line
== ' ' || *line
== '\t')
94 if(Strnicmp(line
, "language", 8) == 0)
100 Language
= AllocString(line
);
103 for(ptr
= Language
; *ptr
; ptr
++)
105 *ptr
= tolower((int)*ptr
);
110 else if(Strnicmp(line
, "version", 7) == 0)
114 CatVersion
= strtol(line
, &line
, 0);
117 else if(Strnicmp(line
, "basename", 8) == 0)
122 BaseName
= AllocString(line
);
125 else if(Strnicmp(line
, "ifdef", 5) == 0)
129 else if(Strnicmp(line
, "endif", 5) == 0)
133 else if(Strnicmp(line
, "array", 5) == 0)
137 else if(Strnicmp(line
, "header", 6) == 0)
142 HeaderName
= AllocString(line
);
146 else if(Strnicmp(line
, "lengthbytes", 11) == 0)
150 lenbytes
= atoi(line
);
153 else if(Strnicmp(line
, "printf_check_off", 16) == 0)
157 else if(Strnicmp(line
, "printf_check_on", 15) == 0)
163 ShowWarn(MSG_ERR_UNKNOWNCDCOMMAND
);
168 if(CheckExtra
== TRUE
)
173 ShowError(MSG_ERR_EXTRA_CHARACTERS
);
182 /* Check for blanks at the start of line. */
184 if(*line
== ' ' || *line
== '\t')
186 ShowError(MSG_ERR_UNEXPECTEDBLANKS
);
192 while((*line
>= 'a' && *line
<= 'z') ||
193 (*line
>= 'A' && *line
<= 'Z') ||
194 (*line
>= '0' && *line
<= '9') ||
202 ShowError(MSG_ERR_NOIDENTIFIER
);
209 if((cs
= malloc(sizeof(*cs
))) == NULL
)
216 struct CatString
*scs
;
219 for(scs
= FirstCatString
; scs
!= NULL
; scs
= scs
->Next
)
221 if(scs
->ID
== NextID
)
229 while(found
== FALSE
);
235 cs
->CD_Str
= (char *)"";
238 cs
->POformat
= FALSE
;
240 if((cs
->ID_Str
= malloc((line
- idstr
) + 1)) == NULL
)
244 strncpy(cs
->ID_Str
, idstr
, line
- idstr
);
245 cs
->ID_Str
[line
- idstr
] = '\0';
248 /* Check if next char in line is '('? (//) */
252 ShowError(MSG_ERR_NO_LEADING_BRACKET
, cs
->ID_Str
);
258 struct CatString
*scs
;
260 int bytesread
, reallen
;
265 /* Check for default config of line (//) */
271 NextID
= cs
->ID
= NextID
+ strtol(line
, &line
, 0);
273 else if(*line
== '$')
276 cs
->ID
= NextID
= strtol(line
, &line
, 16);
280 cs
->ID
= NextID
= strtol(line
, &line
, 0);
285 /* Check for already used identifier. */
287 for(scs
= FirstCatString
; scs
!= NULL
; scs
= scs
->Next
)
289 if(scs
->ID
== cs
->ID
)
291 ShowError(MSG_ERR_DOUBLE_ID
, cs
->ID_Str
);
294 if(strcmp(cs
->ID_Str
, scs
->ID_Str
) == 0)
296 ShowError(MSG_ERR_DOUBLE_IDENTIFIER
, cs
->ID_Str
);
301 /* Check for min/len values (//) */
305 ShowWarn(MSG_ERR_NO_MIN_LEN
, cs
->ID_Str
);
314 cs
->MinLen
= strtol(line
, &line
, 0);
319 ShowWarn(MSG_ERR_NO_MAX_LEN
, cs
->ID_Str
);
328 cs
->MaxLen
= strtol(line
, &line
, 0);
333 ShowError(MSG_ERR_NO_TRAILING_BRACKET
, cs
->ID_Str
);
342 ShowError(MSG_ERR_EXTRA_CHARACTERS_ID
, cs
->ID_Str
);
348 /* Huh? There is no string for this definition? */
350 if((newline
= ReadLine(fp
, FALSE
)) == FALSE
)
352 ShowWarn(MSG_ERR_MISSINGSTRING
);
354 cs
->CD_Str
= (char *)"";
358 // Check if there are any non-ASCII characters contained in the line.
359 // This will cause a warning only, since non-ASCII characters in the
360 // default language are discouraged.
364 while((c
= *p
++) != '\0')
370 ShowWarn(MSG_ERR_NON_ASCII_CHARACTER
, v
& 0xff, cs
->ID_Str
);
375 cs
->CD_Str
= AllocString(newline
);
379 /* Get string length. */
383 while(*oldstr
!= '\0')
385 bytesread
= ReadChar(&oldstr
, bytes
);
390 reallen
+= bytesread
;
393 /* String too short. */
395 if(cs
->MinLen
> 0 && reallen
< cs
->MinLen
)
397 ShowWarn(MSG_ERR_STRING_TOO_SHORT
, cs
->ID_Str
);
400 /* String too long. */
402 if(cs
->MaxLen
> 0 && reallen
> cs
->MaxLen
)
404 ShowWarn(MSG_ERR_STRING_TOO_LONG
, cs
->ID_Str
);
408 cs
->LenBytes
= lenbytes
;