grub2: bring back build of aros-side grub2 tools
[AROS.git] / tools / flexcat / src / createcat.c
blob61d1e71e30d5f1b01376e66a4287423b3a598686
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 "scanct.h"
25 #include "showfuncs.h"
26 #include "readprefs.h"
27 #include "swapfuncs.h"
28 #include "globals.h"
29 #include "utils.h"
31 struct CatString *FirstCatString = NULL; /* First catalog string */
32 struct CatalogChunk *FirstChunk = NULL; /* List of catalog chunks */
34 /// CatPuts
36 /* CatPuts prints a string to a catalog. (The string is preceded by a
37 long integer containing its length and probably padded up to word
38 boundary or longword boundary, depending on the argument padbytes.)
39 The arguments countnul should be TRUE if the NUL byte at the end of
40 the string should be counted. */
42 int CatPuts(FILE *fp, char *str, int padbytes, int countnul, int lenbytes)
44 uint32 reallen;
45 uint32 virtuallen;
46 uint32 chunklen;
47 uint32 swapped_long;
48 int bytesread;
49 char *oldstr;
50 char bytes[10];
52 /* Get length of string */
54 oldstr = str;
55 reallen = 0;
57 while(*oldstr != '\0')
59 bytesread = ReadChar(&oldstr, bytes);
60 // substract one byte for double backslashes
61 if(bytesread == 2)
62 bytesread--;
64 reallen += bytesread;
67 virtuallen = chunklen = reallen + lenbytes;
68 if(countnul || chunklen % padbytes == 0)
69 virtuallen++;
71 swapped_long = SwapLong(virtuallen);
73 fwrite(&swapped_long, sizeof(virtuallen), 1, fp);
74 if(lenbytes > 0)
75 fwrite(((char *)&reallen) + sizeof(reallen) - lenbytes, lenbytes, 1, fp);
77 while(*str != '\0')
79 bytesread = ReadChar(&str, bytes);
80 if(bytesread > 0)
81 fwrite(bytes + bytesread - 1, 1, 1, fp);
86 putc('\0', fp);
88 while(++chunklen % padbytes);
90 return (int)chunklen + 4;
93 ///
94 /// PutCatalogChunk
96 /* This puts a string chunk into the catalog */
98 int PutCatalogChunk(FILE * fp, struct CatalogChunk *cc)
100 fwrite(&cc->ID, sizeof(cc->ID), 1, fp);
102 return 4 + CatPuts(fp, cc->ChunkStr, 2, TRUE, 0);
106 /// CreateCatalog
108 /* This creates a catalog */
110 void CreateCat(char *CatFile)
112 FILE *fp;
113 int CatLen, HeadLen;
114 struct CatString *cs;
115 struct CatalogChunk *cc;
116 int i;
118 if(CatVersionString == NULL && CatRcsId == NULL)
120 ShowError(MSG_ERR_NOCTVERSION);
123 if(CatLanguage == NULL)
125 ShowError(MSG_ERR_NOCTLANGUAGE);
128 if(strlen(CatLanguage) == 0)
130 ShowError(MSG_ERR_NOCTLANGUAGE);
133 if(CatFile == NULL)
135 if(BaseName == NULL)
136 ShowError(MSG_ERR_NOCATFILENAME);
137 else
139 if(asprintf(&CatFile, "%s.catalog", BaseName) < 0)
140 MemError();
144 if((fp = fopen(CatFile, "wb")) == NULL)
146 ShowError(MSG_ERR_NOCATALOG, CatFile);
149 if(!NoBufferedIO)
150 setvbuf(fp, NULL, _IOFBF, buffer_size);
152 fputs("FORM0000CTLG", fp);
153 CatLen = 4;
155 if(CatVersionString !=NULL)
157 struct CatalogChunk verChunk;
158 char *found;
160 verChunk.ID = MAKE_ID('F', 'V', 'E', 'R');
162 verChunk.ChunkStr = strdup(CatVersionString);
164 /* Replace $TODAY placeholder */
166 found = strstr(verChunk.ChunkStr, "$TODAY");
167 if(found != NULL)
169 char dateStr[12];
170 time_t tim;
171 struct tm *t;
172 char *verStr = NULL;
174 time(&tim);
175 t = localtime(&tim);
177 *found = '\0';
178 strftime(dateStr, sizeof(dateStr), "%d.%m.%Y", t);
180 if(asprintf(&verStr, "%s%s%s", verChunk.ChunkStr, dateStr, found + strlen("$TODAY")) != -1)
182 free(verChunk.ChunkStr);
183 verChunk.ChunkStr = verStr;
185 else
186 MemError();
189 /* Replace ".ct" with ".catalog" */
191 found = strstr(verChunk.ChunkStr, ".ct ");
192 if(found != NULL)
194 char *verStr = NULL;
196 *found = '\0';
197 if(asprintf(&verStr, "%s.catalog%s", verChunk.ChunkStr, found + 3) != -1)
199 free(verChunk.ChunkStr);
200 verChunk.ChunkStr = verStr;
204 verChunk.ID = SwapLong(verChunk.ID);
205 CatLen += PutCatalogChunk(fp, &verChunk);
206 free(verChunk.ChunkStr);
208 else
210 struct CatalogChunk verChunk;
211 char *verStr = NULL;
212 int year = 0, month = 0, day = 0;
213 int version = 0, revision = 0;
214 char *name = NULL;
215 char *ptr;
217 if(CatRcsId == NULL)
219 ShowError(MSG_ERR_NOCTVERSION);
221 else
223 if((ptr = strstr(CatRcsId, "$Date:")) == NULL ||
224 sscanf(ptr + 6, " %d/%d/%d", &year, &month, &day) != 3 ||
225 (ptr = strstr(CatRcsId, "$Revision:")) == NULL ||
226 sscanf(ptr + 10, " %d.%d", &version, &revision) != 2)
228 ShowError(MSG_ERR_WRONGRCSID);
230 if((ptr = strstr(CatRcsId, "$Id:")) != NULL)
232 int len = 0;
233 char *found;
235 ptr += 4;
236 OverSpace(&ptr);
237 found = ptr;
239 while(*ptr != '\0' && *ptr != '$' && *ptr != ' ' && *ptr != '\t')
241 ++len;
242 ++ptr;
244 if((name = malloc(len + 1)) == NULL)
246 MemError();
248 strncpy(name, found, len);
249 name[len] = '\0';
253 if(CatName != NULL)
255 name = CatName;
257 else if(name == NULL)
259 ShowError(MSG_ERR_NOCTVERSION);
260 name = (char *)"";
263 if(asprintf(&verStr, "%cVER: %s %d.%d(%d.%d.%d)", '$', name, version, revision, day, month, year) != -1)
265 verChunk.ID = MAKE_ID('F', 'V', 'E', 'R');
266 verChunk.ID = SwapLong(verChunk.ID);
267 verChunk.ChunkStr = verStr;
268 CatLen += PutCatalogChunk(fp, &verChunk);
270 else
271 MemError();
274 for(cc = FirstChunk; cc != NULL; cc = cc->Next)
276 CatLen += PutCatalogChunk(fp, cc);
279 i = 32;
280 fputs("CSET", fp);
283 int i_tmp = SwapLong(i);
285 fwrite(&i_tmp, sizeof(i_tmp), 1, fp);
286 i_tmp = SwapLong(CodeSet);
287 fwrite(&i_tmp, sizeof(i_tmp), 1, fp);
288 i -= sizeof(i_tmp);
291 while(i-- > 0)
293 putc('\0', fp);
296 CatLen += 48;
297 fprintf(fp, "STRS0000");
298 HeadLen = CatLen;
300 for(cs = FirstCatString; cs != NULL; cs = cs->Next)
302 int FillUsed = FALSE;
303 int tmp_ID = SwapLong(cs->ID);
305 if(Fill)
307 if(cs->CT_Str != NULL && cs->NotInCT == FALSE)
309 if(strlen(cs->CT_Str) == 0)
311 fwrite(&tmp_ID, sizeof(tmp_ID), 1, fp);
312 CatLen += 4 + CatPuts(fp, cs->CD_Str, 4, FALSE, cs->LenBytes);
313 FillUsed = TRUE;
316 else
318 fwrite(&tmp_ID, sizeof(cs->ID), 1, fp);
319 CatLen += 4 + CatPuts(fp, cs->CD_Str, 4, FALSE, cs->LenBytes);
320 FillUsed = TRUE;
324 if(FillUsed == FALSE && cs->CT_Str != NULL && cs->NotInCT == FALSE &&
325 (NoOptim ? TRUE : strcmp(cs->CT_Str, cs->CD_Str)))
327 fwrite(&tmp_ID, sizeof(tmp_ID), 1, fp);
328 CatLen += 4 + CatPuts(fp, cs->CT_Str, 4, FALSE, cs->LenBytes);
331 /* printf("LB=%d\n", cs->LenBytes); */
335 int tmp_Len;
337 fseek(fp, 4, SEEK_SET);
339 tmp_Len = SwapLong(CatLen);
340 fwrite(&tmp_Len, sizeof(tmp_Len), 1, fp);
341 fseek(fp, HeadLen - 4, SEEK_CUR);
343 CatLen -= HeadLen;
344 tmp_Len = SwapLong(CatLen);
345 fwrite(&tmp_Len, sizeof(CatLen), 1, fp);
348 fclose(fp);
349 #ifdef AMIGA
350 SetProtection(CatFile, FILE_MASK);
351 #endif
352 Expunge();