Added some SD files which are needed by "contrib".
[AROS.git] / tools / flexcat / src / scancd.c
blobf2ed0cfc01ed717c958735b3d0abd8ab2040ff22
1 /*
2 * $Id$
4 * Copyright (C) 1993-1999 by Jochen Wiedmann and Marcin Orlowski
5 * Copyright (C) 2002-2010 by the 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.
23 #include "flexcat.h"
24 #include "showfuncs.h"
25 #include "readprefs.h"
26 #include "globals.h"
27 #include "utils.h"
28 #include "createcat.h"
30 struct CDLine *FirstCDLine = NULL; /* First catalog description line. */
31 char *HeaderName = NULL;
33 /// ScanCDFile
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)
41 FILE *fp;
42 struct CDLine *cdline, **cdptr = &FirstCDLine;
43 struct CatString *cs, **csptr = &FirstCatString;
44 char *line, *newline;
45 int NextID = 0;
46 int Result = TRUE;
47 int lenbytes = 0;
49 ScanFile = cdfile;
50 ScanLine = 0;
52 if((fp = fopen(cdfile, "r")) == NULL)
54 ShowErrorQuick(MSG_ERR_NOCATALOGDESCRIPTION, cdfile);
57 if(!NoBufferedIO)
58 setvbuf(fp, NULL, _IOFBF, buffer_size);
60 while(!feof(fp) && (line = newline = ReadLine(fp, TRUE)) != NULL)
62 if((cdline = malloc(sizeof(*cdline))) == NULL)
64 MemError();
67 *cdptr = cdline;
68 cdptr = &cdline->Next;
69 cdline->Next = NULL;
70 cdline->Line = line = AllocString(newline);
71 free(newline);
73 if(*line == ';')
75 continue;
77 else if(*line == '#')
79 int CheckExtra = TRUE;
81 /* '#' in the first column of a line is the command introducer --
82 any number of # symbols, blank spaces and tabs afterwards are
83 skipped for compatibility with CatComp */
85 while(*line == '#' || *line == ' ' || *line == '\t')
87 ++line;
90 if(Strnicmp(line, "language", 8) == 0)
92 char *ptr;
94 line += 9;
95 OverSpace(&line);
96 Language = AllocString(line);
97 if(LANGToLower)
99 for(ptr = Language; *ptr; ptr++)
101 *ptr = tolower((int)*ptr);
104 CheckExtra = FALSE;
106 else if(Strnicmp(line, "version", 7) == 0)
108 line += 8;
109 OverSpace(&line);
110 CatVersion = strtol(line, &line, 0);
111 CheckExtra = TRUE;
113 else if(Strnicmp(line, "basename", 8) == 0)
115 line += 9;
116 OverSpace(&line);
117 free(BaseName);
118 BaseName = AllocString(line);
119 CheckExtra = FALSE;
121 else if(Strnicmp(line, "ifdef", 5) == 0)
123 continue;
125 else if(Strnicmp(line, "endif", 5) == 0)
127 continue;
129 else if(Strnicmp(line, "array", 5) == 0)
131 continue;
133 else if(Strnicmp(line, "header", 6) == 0)
135 line += 7;
136 OverSpace(&line);
137 free(HeaderName);
138 HeaderName = AllocString(line);
139 CheckExtra = FALSE;
142 else if(Strnicmp(line, "lengthbytes", 11) == 0)
144 line += 12;
145 OverSpace(&line);
146 lenbytes = atoi(line);
147 CheckExtra = FALSE;
149 else if(Strnicmp(line, "printf_check_off", 16) == 0)
151 continue;
153 else if(Strnicmp(line, "printf_check_on", 15) == 0)
155 continue;
157 else
159 ShowWarn(MSG_ERR_UNKNOWNCDCOMMAND);
160 Result = FALSE;
161 CheckExtra = FALSE;
164 if(CheckExtra == TRUE)
166 OverSpace(&line);
167 if(*line != '\0')
169 ShowError(MSG_ERR_EXTRA_CHARACTERS);
170 Result = FALSE;
174 else
176 char *idstr;
178 /* Check for blanks at the start of line. */
180 if(*line == ' ' || *line == '\t')
182 ShowError(MSG_ERR_UNEXPECTEDBLANKS);
183 Result = FALSE;
184 OverSpace(&line);
187 idstr = line;
188 while((*line >= 'a' && *line <= 'z') ||
189 (*line >= 'A' && *line <= 'Z') ||
190 (*line >= '0' && *line <= '9') ||
191 (*line == '_'))
193 ++line;
196 if(idstr == line)
198 ShowError(MSG_ERR_NOIDENTIFIER);
199 Result = FALSE;
201 else
203 int found;
205 if((cs = malloc(sizeof(*cs))) == NULL)
207 MemError();
212 struct CatString *scs;
214 found = TRUE;
215 for(scs = FirstCatString; scs != NULL; scs = scs->Next)
217 if(scs->ID == NextID)
219 found = FALSE;
220 ++NextID;
221 break;
225 while(found == FALSE);
227 cs->Next = NULL;
228 cs->ID = NextID;
229 cs->MinLen = 0;
230 cs->MaxLen = -1;
231 cs->CD_Str = (char *)"";
232 cs->CT_Str = NULL;
233 cs->NotInCT = TRUE;
234 cs->POformat = FALSE;
236 if((cs->ID_Str = malloc((line - idstr) + 1)) == NULL)
238 MemError();
240 strncpy(cs->ID_Str, idstr, line - idstr);
241 cs->ID_Str[line - idstr] = '\0';
242 OverSpace(&line);
244 /* Check if next char in line is '('? (//) */
246 if(*line != '(')
248 ShowError(MSG_ERR_NO_LEADING_BRACKET, cs->ID_Str);
249 Result = FALSE;
251 else
253 char *oldstr;
254 struct CatString *scs;
255 char bytes[10];
256 int bytesread, reallen;
258 ++line;
259 OverSpace(&line);
261 /* Check for default config of line (//) */
263 if(*line != '/')
265 if(*line == '+')
267 NextID = cs->ID = NextID + strtol(line, &line, 0);
269 else if(*line == '$')
271 line++;
272 cs->ID = NextID = strtol(line, &line, 16);
274 else
276 cs->ID = NextID = strtol(line, &line, 0);
278 OverSpace(&line);
281 /* Check for already used identifier. */
283 for(scs = FirstCatString; scs != NULL; scs = scs->Next)
285 if(scs->ID == cs->ID)
287 ShowError(MSG_ERR_DOUBLE_ID, cs->ID_Str);
288 Result = FALSE;
290 if(strcmp(cs->ID_Str, scs->ID_Str) == 0)
292 ShowError(MSG_ERR_DOUBLE_IDENTIFIER, cs->ID_Str);
293 Result = FALSE;
297 /* Check for min/len values (//) */
299 if(*line != '/')
301 ShowWarn(MSG_ERR_NO_MIN_LEN, cs->ID_Str);
302 Result = FALSE;
304 else
306 ++line;
307 OverSpace(&line);
308 if(*line != '/')
310 cs->MinLen = strtol(line, &line, 0);
311 OverSpace(&line);
313 if(*line != '/')
315 ShowWarn(MSG_ERR_NO_MAX_LEN, cs->ID_Str);
316 Result = FALSE;
318 else
320 ++line;
321 OverSpace(&line);
322 if(*line != ')')
324 cs->MaxLen = strtol(line, &line, 0);
325 OverSpace(&line);
327 if(*line != ')')
329 ShowError(MSG_ERR_NO_TRAILING_BRACKET, cs->ID_Str);
330 Result = FALSE;
332 else
334 ++line;
335 OverSpace(&line);
336 if(*line)
338 ShowError(MSG_ERR_EXTRA_CHARACTERS_ID, cs->ID_Str);
344 /* Huh? There is no string for this definition? */
346 if((newline = ReadLine(fp, FALSE)) == FALSE)
348 ShowWarn(MSG_ERR_MISSINGSTRING);
349 Result = FALSE;
350 cs->CD_Str = (char *)"";
352 else
354 // Check if there are any non-ASCII characters contained in the line.
355 // This will cause a warning only, since non-ASCII characters in the
356 // default language are discouraged.
357 char *p = newline;
358 char c;
360 while((c = *p++) != '\0')
362 if(!isascii(c))
364 int v = (int)c;
366 ShowWarn(MSG_ERR_NON_ASCII_CHARACTER, v & 0xff, cs->ID_Str);
367 break;
371 cs->CD_Str = AllocString(newline);
372 free(newline);
375 /* Get string length. */
377 oldstr = cs->CD_Str;
378 reallen = 0;
379 while(*oldstr != '\0')
381 bytesread = ReadChar(&oldstr, bytes);
382 if(bytesread == 2)
384 bytesread--;
386 reallen += bytesread;
389 /* String too short. */
391 if(cs->MinLen > 0 && reallen < cs->MinLen)
393 ShowWarn(MSG_ERR_STRING_TOO_SHORT, cs->ID_Str);
396 /* String too long. */
398 if(cs->MaxLen > 0 && reallen > cs->MaxLen)
400 ShowWarn(MSG_ERR_STRING_TOO_LONG, cs->ID_Str);
403 cs->Nr = NumStrings;
404 cs->LenBytes = lenbytes;
405 *csptr = cs;
406 csptr = &cs->Next;
407 ++NumStrings;
413 fclose(fp);
415 return Result;