gwenhywfar 5.10.1
utils.c
Go to the documentation of this file.
1/***************************************************************************
2 begin : Mon Feb 08 2021
3 copyright : (C) 2021 by Martin Preuss
4 email : martin@libchipcard.de
5
6 ***************************************************************************
7 * Please see toplevel file COPYING for license details *
8 ***************************************************************************/
9
10#ifdef HAVE_CONFIG_H
11# include <config.h>
12#endif
13
14
15#include "utils.h"
16
17#include <gwenhywfar/debug.h>
18#include <gwenhywfar/directory.h>
19#include <gwenhywfar/buffer.h>
20
21#include <unistd.h>
22#include <sys/types.h>
23#include <sys/stat.h>
24#include <time.h>
25#include <stdio.h>
26#include <stdlib.h>
27#include <errno.h>
28#include <ctype.h>
29
30
31
32static GWB_KEYVALUEPAIR_LIST *_generateInstallList(const GWB_FILE_LIST2 *fileList, const char *initialSourceDir);
33static int _filesChanged(const char *fileName, GWEN_STRINGLIST *slFileNameList);
34static GWEN_STRINGLIST *_readBuildFileList(const char *fileName);
35static void _writeProjectNameAndVersionToXml(const GWB_PROJECT *project, GWEN_XMLNODE *xmlNode);
36static int _readIntUntilPointOrHyphen(const char **ptrToStringPtr);
37static int _readAndStoreNextVersionPart(const char **s, GWEN_DB_NODE *db, const char *varNamePrefix, const char *varName);
38
39
40
41
42int GWB_Utils_WriteProjectFileList(const GWB_PROJECT *project, const char *fileName)
43{
44 GWB_FILE_LIST2 *fileList;
45
46 fileList=GWB_Project_GetFileList(project);
47 if (fileList) {
48 GWEN_XMLNODE *xmlNode;
49 GWEN_XMLNODE *xmlFileList;
50 int rv;
51
53 xmlFileList=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, "FileList");
54 GWB_File_List2_WriteXml(fileList, xmlFileList, "file");
55 GWEN_XMLNode_AddChild(xmlNode, xmlFileList);
56
58 GWEN_XMLNode_free(xmlNode);
59 if (rv<0) {
60 DBG_ERROR(NULL, "Error writing FileList to file \"%s\" (%d)", fileName, rv);
61 return rv;
62 }
63
64 }
65
66 return 0;
67}
68
69
70
71GWB_FILE_LIST2 *GWB_Utils_ReadFileList2(const char *fileName)
72{
73 GWEN_XMLNODE *xmlRoot;
74 GWEN_XMLNODE *xmlFileList;
75 int rv;
76
79 if (rv<0) {
80 DBG_ERROR(NULL, "Error reading build file list from \"%s\"", fileName);
81 GWEN_XMLNode_free(xmlRoot);
82 return NULL;
83 }
84
85 xmlFileList=GWEN_XMLNode_FindFirstTag(xmlRoot, "FileList", NULL, NULL);
86 if (xmlFileList) {
87 GWB_FILE_LIST2 *fileList;
88
89 fileList=GWB_File_List2_new();
90 GWB_File_List2_ReadXml(xmlFileList, "file", fileList);
91 if (GWB_File_List2_GetSize(fileList)==0) {
92 GWB_File_List2_free(fileList);
93 GWEN_XMLNode_free(xmlRoot);
94 return NULL;
95 }
96
97 return fileList;
98 }
99
100 GWEN_XMLNode_free(xmlRoot);
101 return NULL;
102}
103
104
105
106int GWB_Utils_WriteBuildFileList(const GWENBUILD *gwenbuild, const char *fileName)
107{
108 GWEN_STRINGLIST *sl;
109
110 sl=GWBUILD_GetBuildFilenameList(gwenbuild);
111 if (sl) {
112 GWEN_XMLNODE *xmlRoot;
113 GWEN_XMLNODE *xmlFileList;
115 int rv;
116
117 xmlRoot=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, "root");
118 xmlFileList=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, "BuildFiles");
119 GWEN_XMLNode_AddChild(xmlRoot, xmlFileList);
120
122 while(se) {
123 const char *s;
124
126 if (s && *s) {
127 GWEN_XMLNODE *xmlFile;
128 GWEN_XMLNODE *xmlFileName;
129
130 xmlFile=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, "File");
132 GWEN_XMLNode_AddChild(xmlFile, xmlFileName);
133 GWEN_XMLNode_AddChild(xmlFileList, xmlFile);
134 }
135
137 }
138
140 GWEN_XMLNode_free(xmlRoot);
141 if (rv<0) {
142 DBG_ERROR(NULL, "Error writing build file list to file \"%s\" (%d)", fileName, rv);
143 return rv;
144 }
145 }
146
147 return 0;
148}
149
150
151
152int GWB_Utils_WriteInstallFileList(const GWB_PROJECT *project, const char *fileName)
153{
154 GWB_KEYVALUEPAIR_LIST *genFileList;
155 const char *initialSourceDir;
156
158
159 genFileList=_generateInstallList(GWB_Project_GetFileList(project), initialSourceDir);
160 if (genFileList) {
161 GWB_KEYVALUEPAIR *kvp;
162 GWEN_XMLNODE *xmlRoot;
163 GWEN_XMLNODE *xmlFileList;
164 int rv;
165
166 xmlRoot=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, "root");
167 xmlFileList=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, "InstallFiles");
168 GWEN_XMLNode_AddChild(xmlRoot, xmlFileList);
169
170 kvp=GWB_KeyValuePair_List_First(genFileList);
171 while(kvp) {
172 const char *sDestPath;
173 const char *sSrcPath;
174
175 sDestPath=GWB_KeyValuePair_GetKey(kvp);
176 sSrcPath=GWB_KeyValuePair_GetValue(kvp);
177 if (sDestPath && sSrcPath) {
178 GWEN_XMLNODE *xmlFile;
179
180 xmlFile=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, "InstallFile");
181 GWEN_XMLNode_SetCharValue(xmlFile, "destination", sDestPath);
182 GWEN_XMLNode_SetCharValue(xmlFile, "source", sSrcPath);
183 GWEN_XMLNode_AddChild(xmlFileList, xmlFile);
184 }
185
186 kvp=GWB_KeyValuePair_List_Next(kvp);
187 }
188
190 GWEN_XMLNode_free(xmlRoot);
191 if (rv<0) {
192 DBG_ERROR(NULL, "Error writing build file list to file \"%s\" (%d)", fileName, rv);
193 return rv;
194 }
195 }
196
197 return 0;
198}
199
200
201
202GWB_KEYVALUEPAIR_LIST *GWB_Utils_ReadInstallFileList(const char *fileName)
203{
204 GWEN_XMLNODE *xmlRoot;
205 GWEN_XMLNODE *xmlFileList;
206 int rv;
207
208 xmlRoot=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, "root");
210 if (rv<0) {
211 DBG_ERROR(NULL, "Error reading build file list from \"%s\"", fileName);
212 GWEN_XMLNode_free(xmlRoot);
213 return NULL;
214 }
215
216 xmlFileList=GWEN_XMLNode_FindFirstTag(xmlRoot, "InstallFiles", NULL, NULL);
217 if (xmlFileList) {
218 GWB_KEYVALUEPAIR_LIST *kvpList;
219 GWEN_XMLNODE *xmlFile;
220
221 kvpList=GWB_KeyValuePair_List_new();
222 xmlFile=GWEN_XMLNode_FindFirstTag(xmlFileList, "InstallFile", NULL, NULL);
223 while(xmlFile) {
224 GWB_KEYVALUEPAIR *kvp;
225 const char *sDestPath;
226 const char *sSrcPath;
227
228 sDestPath=GWEN_XMLNode_GetCharValue(xmlFile, "destination", NULL);
229 sSrcPath=GWEN_XMLNode_GetCharValue(xmlFile, "source", NULL);
230 kvp=GWB_KeyValuePair_new(sDestPath, sSrcPath);
231 GWB_KeyValuePair_List_Add(kvp, kvpList);
232
233 xmlFile=GWEN_XMLNode_FindNextTag(xmlFile, "InstallFile", NULL, NULL);
234 }
235 GWEN_XMLNode_free(xmlRoot);
236
237 if (GWB_KeyValuePair_List_GetCount(kvpList)==0) {
238 GWB_KeyValuePair_List_free(kvpList);
239 return NULL;
240 }
241
242 return kvpList;
243 }
244
245 GWEN_XMLNode_free(xmlRoot);
246 return NULL;
247}
248
249
250
251GWB_KEYVALUEPAIR_LIST *_generateInstallList(const GWB_FILE_LIST2 *fileList, const char *initialSourceDir)
252{
253 if (fileList) {
254 GWB_FILE_LIST2_ITERATOR *it;
255
256 it=GWB_File_List2_First(fileList);
257 if (it) {
258 GWB_FILE *file;
259 GWB_KEYVALUEPAIR_LIST *kvpList;
260 GWEN_BUFFER *keyBuf;
261 GWEN_BUFFER *valueBuf;
262
263 keyBuf=GWEN_Buffer_new(0, 256, 0, 1);
264 valueBuf=GWEN_Buffer_new(0, 256, 0, 1);
265 kvpList=GWB_KeyValuePair_List_new();
266 file=GWB_File_List2Iterator_Data(it);
267 while(file) {
269 const char *s;
270 GWB_KEYVALUEPAIR *kvp;
271
273 if (s && *s) {
274 const char *destFileName;
275
276 destFileName=GWB_File_GetInstallName(file);
277 if (!(destFileName && *destFileName))
278 destFileName=GWB_File_GetName(file);
279 GWEN_Buffer_AppendString(keyBuf, s);
281 GWEN_Buffer_AppendString(keyBuf, destFileName);
282
283 GWB_File_WriteFileNameToTopBuildDirString(file, initialSourceDir, valueBuf);
285 GWB_KeyValuePair_List_Add(kvp, kvpList);
286 GWEN_Buffer_Reset(valueBuf);
287 GWEN_Buffer_Reset(keyBuf);
288 }
289 }
290 file=GWB_File_List2Iterator_Next(it);
291 }
292 GWEN_Buffer_free(valueBuf);
293 GWEN_Buffer_free(keyBuf);
294 GWB_File_List2Iterator_free(it);
295 if (GWB_KeyValuePair_List_GetCount(kvpList)==0) {
296 GWB_KeyValuePair_List_free(kvpList);
297 return NULL;
298 }
299 return kvpList;
300 }
301 }
302
303 return NULL;
304}
305
306
307
308int GWB_Utils_BuildFilesChanged(const char *fileName)
309{
310 GWEN_STRINGLIST *slFileNameList;
311
312 slFileNameList=_readBuildFileList(fileName);
313 if (slFileNameList) {
314 if (_filesChanged(fileName, slFileNameList)) {
315 GWEN_StringList_free(slFileNameList);
316 return 1;
317 }
318 GWEN_StringList_free(slFileNameList);
319 }
320
321 return 0;
322}
323
324
325
326int _filesChanged(const char *fileName, GWEN_STRINGLIST *slFileNameList)
327{
328 time_t mtSourceFile;
330
331 mtSourceFile=GWBUILD_GetModificationTimeOfFile(fileName);
332 if (mtSourceFile==(time_t) 0) {
333 DBG_INFO(NULL, "here");
334 return 1; /* assume changed */
335 }
336
337 se=GWEN_StringList_FirstEntry(slFileNameList);
338 while(se) {
339 const char *s;
340
342 if (s && *s) {
343 time_t mt;
344
346 if (mt!=(time_t) 0) {
347 if (difftime(mt, mtSourceFile)>0) {
348 DBG_ERROR(NULL, "File \"%s\" changed.", s);
349 return 1;
350 }
351 }
352 }
353
355 }
356
357 DBG_DEBUG(NULL, "Files unchanged since last setup.");
358 return 0;
359}
360
361
362
364{
365 GWEN_XMLNODE *xmlRoot;
366 GWEN_XMLNODE *xmlFileList;
367 int rv;
368
369 xmlRoot=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, "root");
371 if (rv<0) {
372 DBG_ERROR(NULL, "Error reading build file list from \"%s\"", fileName);
373 GWEN_XMLNode_free(xmlRoot);
374 return NULL;
375 }
376
377 xmlFileList=GWEN_XMLNode_FindFirstTag(xmlRoot, "BuildFiles", NULL, NULL);
378 if (xmlFileList) {
379 GWEN_STRINGLIST *sl;
380 GWEN_XMLNODE *xmlFile;
381
383 xmlFile=GWEN_XMLNode_FindFirstTag(xmlFileList, "File", NULL, NULL);
384 while(xmlFile) {
385 GWEN_XMLNODE *xmlFileName;
386
387 xmlFileName=GWEN_XMLNode_GetFirstData(xmlFile);
388 if (xmlFileName) {
389 const char *s;
390
391 s=GWEN_XMLNode_GetData(xmlFileName);
392 if (s && *s)
393 GWEN_StringList_AppendString(sl, s, 0, 1);
394 }
395
396 xmlFile=GWEN_XMLNode_FindNextTag(xmlFile, "File", NULL, NULL);
397 }
398
399 if (GWEN_StringList_Count(sl)==0) {
401 GWEN_XMLNode_free(xmlRoot);
402 return NULL;
403 }
404 GWEN_XMLNode_free(xmlRoot);
405 return sl;
406 }
407
408 GWEN_XMLNode_free(xmlRoot);
409 return NULL;
410}
411
412
413
414int GWB_Utils_WriteProjectToFile(const GWB_PROJECT *project, const char *fileName)
415{
416 GWEN_XMLNODE *xmlRoot;
417 GWEN_XMLNODE *xmlProject;
418 int rv;
419
420 xmlRoot=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, "root");
421 xmlProject=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, "Project");
422 GWB_Project_toXml(project, xmlProject);
423 GWEN_XMLNode_AddChild(xmlRoot, xmlProject);
424
426 GWEN_XMLNode_free(xmlRoot);
427 if (rv<0) {
428 DBG_ERROR(NULL, "Error writing project to file \"%s\" (%d)", fileName, rv);
429 return rv;
430 }
431
432 return 0;
433}
434
435
436
437int GWB_Utils_WriteContextTreeToFile(const GWB_CONTEXT *ctx, const char *fileName)
438{
439 GWEN_XMLNODE *xmlRoot;
440 GWEN_XMLNODE *xmlContext;
441 int rv;
442
443 xmlRoot=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, "root");
444 xmlContext=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, "ContextTree");
445 GWB_Context_toXml(ctx, xmlContext, 1);
446 GWEN_XMLNode_AddChild(xmlRoot, xmlContext);
447
449 GWEN_XMLNode_free(xmlRoot);
450 if (rv<0) {
451 DBG_ERROR(NULL, "Error writing context tree to file \"%s\" (%d)", fileName, rv);
452 return rv;
453 }
454
455 return 0;
456}
457
458
459
460int GWB_Utils_CopyFile(const char *sSrcPath, const char *sDestPath)
461{
462 int rv;
463 struct stat st;
464
465#if _BSD_SOURCE || _XOPEN_SOURCE >= 500 || _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED
466 rv=lstat(sSrcPath, &st);
467#else
468 rv=stat(sSrcPath, &st);
469#endif
470 if (rv == -1) {
471 DBG_ERROR(NULL, "ERROR: stat(%s): %s", sSrcPath, strerror(errno));
472 return GWEN_ERROR_GENERIC;
473 }
474
475#if ((_BSD_SOURCE || _XOPEN_SOURCE >= 500 || (_XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED) || _POSIX_C_SOURCE >= 200112L) && !defined(__MINGW32__)) || defined(OS_DARWIN)
476 if ((st.st_mode & S_IFMT)==S_IFLNK) {
477 char *symlinkbuf;
478 int bufSizeNeeded;
479
480 /* copy symlink */
481 if (st.st_size==0)
482 bufSizeNeeded=256;
483 else
484 bufSizeNeeded=st.st_size+1;
485 symlinkbuf=(char*) malloc(bufSizeNeeded);
486 assert(symlinkbuf);
487 rv=readlink(sSrcPath, symlinkbuf, bufSizeNeeded);
488 if (rv==-1) {
489 DBG_ERROR(NULL, "ERROR: readlink(%s): %s", sSrcPath, strerror(errno));
490 free(symlinkbuf);
491 return GWEN_ERROR_GENERIC;
492 }
493 else if (rv==bufSizeNeeded) {
494 DBG_ERROR(NULL, "Buffer too small (%d)", bufSizeNeeded);
495 free(symlinkbuf);
496 return GWEN_ERROR_GENERIC;
497 }
498
499 rv=GWEN_Directory_GetPath(sDestPath,
503 if (rv<0) {
504 DBG_INFO(NULL, "here (%d)", rv);
505 free(symlinkbuf);
506 return rv;
507 }
508 unlink(sDestPath);
509 rv=symlink(symlinkbuf, sDestPath);
510 if (rv==-1) {
511 DBG_ERROR(NULL, "ERROR: symlink(%s): %s", sSrcPath, strerror(errno));
512 free(symlinkbuf);
513 return GWEN_ERROR_GENERIC;
514 }
515 }
516 else
517#endif
518 if ((st.st_mode & S_IFMT)==S_IFREG) {
519 mode_t newMode=0;
520
521 rv=GWEN_Directory_GetPath(sDestPath,
525 if (rv<0) {
526 DBG_INFO(NULL, "here (%d)", rv);
527 return rv;
528 }
529
530 rv=GWEN_SyncIo_Helper_CopyFile(sSrcPath, sDestPath);
531 if (rv<0) {
532 DBG_INFO(NULL, "here (%d)", rv);
533 return rv;
534 }
535
536 newMode=S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH;
537 if (st.st_mode & S_IXUSR)
538 newMode|=S_IXUSR|S_IXGRP|S_IXOTH;
539 rv=chmod(sDestPath, newMode);
540 if (rv<0) {
541 DBG_ERROR(NULL, "ERROR: chmod(%s): %s", sSrcPath, strerror(errno));
542 return rv;
543 }
544 }
545 else {
546 DBG_ERROR(NULL, "Unhandled file type \"%s\"", sSrcPath);
547 }
548
549 return 0;
550}
551
552
553
554int GWB_Utils_WriteProjectInfoToFile(const GWB_PROJECT *project, const char *fileName)
555{
556 GWB_CONTEXT *rootContext;
557 GWEN_XMLNODE *xmlRoot;
558 GWEN_XMLNODE *xmlProject;
559 const char *initialSourceDir;
560 int rv;
561
562 rootContext=GWB_Project_GetRootContext(project);
563 initialSourceDir=GWB_Context_GetInitialSourceDir(rootContext);
564
565 xmlRoot=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, "root");
566 xmlProject=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, "ProjectInfo");
567 if (initialSourceDir && *initialSourceDir)
568 GWEN_XMLNode_SetCharValue(xmlProject, "initialSourceDir", initialSourceDir);
569 _writeProjectNameAndVersionToXml(project, xmlProject);
570 GWEN_XMLNode_AddChild(xmlRoot, xmlProject);
571
573 GWEN_XMLNode_free(xmlRoot);
574 if (rv<0) {
575 DBG_ERROR(NULL, "Error writing project to file \"%s\" (%d)", fileName, rv);
576 return rv;
577 }
578
579 return 0;
580}
581
582
583
585{
586 const char *s;
588 if (s)
589 GWEN_XMLNode_SetCharValue(xmlNode, "projectName", s);
590 GWEN_XMLNode_SetIntValue(xmlNode, "versionMajor", GWB_Project_GetVersionMajor(project));
591 GWEN_XMLNode_SetIntValue(xmlNode, "versionMinor", GWB_Project_GetVersionMinor(project));
592 GWEN_XMLNode_SetIntValue(xmlNode, "versionPatchlevel", GWB_Project_GetVersionPatchlevel(project));
593 GWEN_XMLNode_SetIntValue(xmlNode, "versionBuild", GWB_Project_GetVersionBuild(project));
594 s=GWB_Project_GetVersionTag(project);
595 if (s)
596 GWEN_XMLNode_SetCharValue(xmlNode, "versionTag", s);
597
598}
599
600
601
603{
604 GWEN_XMLNODE *xmlRoot;
605 GWEN_XMLNODE *xmlProjectInfo;
606 int rv;
607
608 xmlRoot=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, "root");
610 if (rv<0) {
611 DBG_ERROR(NULL, "Error reading project info from \"%s\"", fileName);
612 GWEN_XMLNode_free(xmlRoot);
613 return NULL;
614 }
615
616 xmlProjectInfo=GWEN_XMLNode_FindFirstTag(xmlRoot, "ProjectInfo", NULL, NULL);
617 if (xmlProjectInfo) {
618 GWEN_XMLNode_UnlinkChild(xmlRoot, xmlProjectInfo);
619 GWEN_XMLNode_free(xmlRoot);
620 return xmlProjectInfo;
621 }
622
623 GWEN_XMLNode_free(xmlRoot);
624 return NULL;
625}
626
627
628
629
630int GWB_Utils_VersionStringToDb(GWEN_DB_NODE *db, const char *prefix, const char *s)
631{
632 const char *p;
633 int rv;
634
635 p=s;
636 while(*p && *p<33)
637 s++;
638 if (isdigit(*p)) {
639 rv=_readAndStoreNextVersionPart(&p, db, prefix, "vmajor");
640 if (rv<0) {
641 DBG_ERROR(NULL, "Invalid version spec \"%s\"", s);
642 return rv;
643 }
644 }
645 if (*p=='.') {
646 rv=_readAndStoreNextVersionPart(&p, db, prefix, "vminor");
647 if (rv<0) {
648 DBG_ERROR(NULL, "Invalid version spec \"%s\"", s);
649 return rv;
650 }
651 }
652 if (*p=='.') {
653 rv=_readAndStoreNextVersionPart(&p, db, prefix, "vpatchlevel");
654 if (rv<0) {
655 DBG_ERROR(NULL, "Invalid version spec \"%s\"", s);
656 return rv;
657 }
658 }
659 if (*p=='.') {
660 rv=_readAndStoreNextVersionPart(&p, db, prefix, "vbuild");
661 if (rv<0) {
662 DBG_ERROR(NULL, "Invalid version spec \"%s\"", s);
663 return rv;
664 }
665 }
666 if (*p=='-') {
667 p++;
668 if (prefix && *prefix) {
669 GWEN_BUFFER *buf;
670
671 buf=GWEN_Buffer_new(0, 256, 0, 1);
672 GWEN_Buffer_AppendString(buf, prefix);
673 GWEN_Buffer_AppendString(buf, "vtag");
675 GWEN_Buffer_free(buf);
676 }
677 else
679 }
680
681 return 0;
682}
683
684
685
686int _readAndStoreNextVersionPart(const char **s, GWEN_DB_NODE *db, const char *varNamePrefix, const char *varName)
687{
688 const char *p;
689 int rv;
690
691 p=*s;
692 if (*p=='.')
693 p++;
695 if (rv<0) {
696 DBG_ERROR(NULL, "Invalid version spec \"%s\"", *s);
697 return GWEN_ERROR_GENERIC;
698 }
699
700 if (varNamePrefix && *varNamePrefix) {
701 GWEN_BUFFER *buf;
702
703 buf=GWEN_Buffer_new(0, 256, 0, 1);
704 GWEN_Buffer_AppendString(buf, varNamePrefix);
705 GWEN_Buffer_AppendString(buf, varName);
707 GWEN_Buffer_free(buf);
708 }
709 else
711 *s=p;
712 return 0;
713}
714
715
716
718{
719 const char *p;
720 unsigned int vmajor=0;
721 unsigned int vminor=0;
722 unsigned int vpatchlevel=0;
723 unsigned int vbuild=0;
724 int rv;
725
726 p=s;
727 while(*p && *p<33)
728 s++;
729 if (isdigit(*p)) {
731 if (rv<0) {
732 DBG_ERROR(NULL, "Invalid version spec \"%s\"", s);
733 return GWEN_ERROR_GENERIC;
734 }
735 vmajor=rv & 0xff;
736 }
737 if (*p=='.') {
738 p++;
740 if (rv<0) {
741 DBG_ERROR(NULL, "Invalid version spec \"%s\"", s);
742 return GWEN_ERROR_GENERIC;
743 }
744 vminor=rv & 0xff;
745 }
746 if (*p=='.') {
747 p++;
749 if (rv<0) {
750 DBG_ERROR(NULL, "Invalid version spec \"%s\"", s);
751 return GWEN_ERROR_GENERIC;
752 }
753 vpatchlevel=rv & 0xff;
754 }
755 if (*p=='.') {
756 p++;
758 if (rv<0) {
759 DBG_ERROR(NULL, "Invalid version spec \"%s\"", s);
760 return GWEN_ERROR_GENERIC;
761 }
762 vbuild=rv & 0xff;
763 }
764
765 return (int) ((vmajor<<24)+(vminor<<16)+(vpatchlevel<<8)+vbuild);
766}
767
768
769
770int _readIntUntilPointOrHyphen(const char **s)
771{
772 int i=0;
773 const char *p;
774
775 p=*s;
776 while(*p && *p!='.' && *p!='-') {
777 int c;
778
779 c=(*p)-'0';
780 if (c<0 || c>9) {
781 DBG_ERROR(NULL, "Invalid version string \"%s\"", *s);
782 return GWEN_ERROR_GENERIC;
783 }
784 i=(i*10)+c;
785 p++;
786 }
787 *s=p;
788
789 return i;
790}
791
792
793
794void GWB_Utils_VersionToDbVar(GWEN_DB_NODE *db, const char *dbVarName,
795 int vmajor, int vminor, int vpatchlevel, int vbuild,
796 const char *vtag) {
797 GWEN_BUFFER *dbuf;
798
799 dbuf=GWEN_Buffer_new(0, 256, 0, 1);
800
801 if (vbuild>0)
802 GWEN_Buffer_AppendArgs(dbuf, "%d.%d.%d.%d", vmajor, vminor, vpatchlevel, vbuild);
803 else
804 GWEN_Buffer_AppendArgs(dbuf, "%d.%d.%d", vmajor, vminor, vpatchlevel);
805
806 if (vtag && *vtag) {
807 GWEN_Buffer_AppendString(dbuf, "-");
808 GWEN_Buffer_AppendArgs(dbuf, "%s", vtag);
809 }
810
812 GWEN_Buffer_free(dbuf);
813}
814
815
816
#define NULL
Definition: binreloc.c:300
GWEN_BUFFER * GWEN_Buffer_new(char *buffer, uint32_t size, uint32_t used, int take)
Definition: buffer.c:42
int GWEN_Buffer_AppendArgs(GWEN_BUFFER *bf, const char *fmt,...)
Definition: buffer.c:1084
void GWEN_Buffer_Reset(GWEN_BUFFER *bf)
Definition: buffer.c:650
void GWEN_Buffer_free(GWEN_BUFFER *bf)
Definition: buffer.c:89
int GWEN_Buffer_AppendString(GWEN_BUFFER *bf, const char *buffer)
Definition: buffer.c:989
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition: buffer.c:235
void GWB_Context_toXml(const GWB_CONTEXT *ctx, GWEN_XMLNODE *xmlNode, int withDb)
Definition: context.c:512
const char * GWB_Context_GetInitialSourceDir(const GWB_CONTEXT *ctx)
Definition: context.c:285
struct GWB_CONTEXT GWB_CONTEXT
Definition: context.h:17
int GWEN_DB_SetIntValue(GWEN_DB_NODE *n, uint32_t flags, const char *path, int val)
Definition: db.c:1202
int GWEN_DB_SetCharValue(GWEN_DB_NODE *n, uint32_t flags, const char *path, const char *val)
Definition: db.c:997
#define GWEN_DB_FLAGS_OVERWRITE_VARS
Definition: db.h:121
struct GWEN_DB_NODE GWEN_DB_NODE
Definition: db.h:228
#define DBG_DEBUG(dbg_logger, format, args...)
Definition: debug.h:214
#define DBG_INFO(dbg_logger, format, args...)
Definition: debug.h:181
#define DBG_ERROR(dbg_logger, format, args...)
Definition: debug.h:97
#define GWEN_DIR_FLAGS_PUBLIC_NAME
Definition: directory.h:61
GWENHYWFAR_API int GWEN_Directory_GetPath(const char *path, unsigned int flags)
#define GWEN_DIR_FLAGS_PUBLIC_PATH
Definition: directory.h:60
#define GWEN_ERROR_GENERIC
Definition: error.h:62
void GWB_File_List2_WriteXml(const GWB_FILE_LIST2 *fileList, GWEN_XMLNODE *xmlNode, const char *groupName)
Definition: file.c:670
void GWB_File_List2_ReadXml(GWEN_XMLNODE *xmlNode, const char *groupName, GWB_FILE_LIST2 *destFileList)
Definition: file.c:693
const char * GWB_File_GetName(const GWB_FILE *f)
Definition: file.c:146
void GWB_File_WriteFileNameToTopBuildDirString(const GWB_FILE *file, const char *initialSourceDir, GWEN_BUFFER *fbuf)
Definition: file.c:473
uint32_t GWB_File_GetFlags(const GWB_FILE *f)
Definition: file.c:99
const char * GWB_File_GetInstallPath(const GWB_FILE *f)
Definition: file.c:208
const char * GWB_File_GetInstallName(const GWB_FILE *f)
Definition: file.c:165
struct GWB_FILE GWB_FILE
Definition: file.h:18
#define GWB_FILE_FLAGS_INSTALL
Definition: file.h:22
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition: buffer.h:38
GWEN_STRINGLIST * GWBUILD_GetBuildFilenameList(const GWENBUILD *gwenbuild)
Definition: gwenbuild.c:140
time_t GWBUILD_GetModificationTimeOfFile(const char *filename)
Definition: gwenbuild.c:885
struct GWENBUILD GWENBUILD
Definition: gwenbuild.h:15
#define GWEN_DIR_SEPARATOR_S
const char * GWB_KeyValuePair_GetValue(const GWB_KEYVALUEPAIR *kvp)
Definition: keyvaluepair.c:97
const char * GWB_KeyValuePair_GetKey(const GWB_KEYVALUEPAIR *kvp)
Definition: keyvaluepair.c:79
GWB_KEYVALUEPAIR * GWB_KeyValuePair_new(const char *key, const char *value)
Definition: keyvaluepair.c:34
struct GWB_KEYVALUEPAIR GWB_KEYVALUEPAIR
Definition: keyvaluepair.h:19
#define GWEN_PATH_FLAGS_CHECKROOT
Definition: path.h:142
#define GWEN_PATH_FLAGS_VARIABLE
Definition: path.h:111
void GWB_Project_toXml(const GWB_PROJECT *project, GWEN_XMLNODE *xmlNode)
Definition: project.c:420
int GWB_Project_GetVersionPatchlevel(const GWB_PROJECT *project)
Definition: project.c:122
GWB_CONTEXT * GWB_Project_GetRootContext(const GWB_PROJECT *project)
Definition: project.c:226
int GWB_Project_GetVersionMinor(const GWB_PROJECT *project)
Definition: project.c:115
GWB_FILE_LIST2 * GWB_Project_GetFileList(const GWB_PROJECT *project)
Definition: project.c:205
const char * GWB_Project_GetVersionTag(const GWB_PROJECT *project)
Definition: project.c:136
int GWB_Project_GetVersionMajor(const GWB_PROJECT *project)
Definition: project.c:108
const char * GWB_Project_GetProjectName(const GWB_PROJECT *project)
Definition: project.c:77
int GWB_Project_GetVersionBuild(const GWB_PROJECT *project)
Definition: project.c:129
struct GWB_PROJECT GWB_PROJECT
Definition: project.h:14
void GWEN_StringList_free(GWEN_STRINGLIST *sl)
Definition: stringlist.c:62
const char * GWEN_StringListEntry_Data(const GWEN_STRINGLISTENTRY *se)
Definition: stringlist.c:406
GWEN_STRINGLISTENTRY * GWEN_StringListEntry_Next(const GWEN_STRINGLISTENTRY *se)
Definition: stringlist.c:398
unsigned int GWEN_StringList_Count(const GWEN_STRINGLIST *sl)
Definition: stringlist.c:427
int GWEN_StringList_AppendString(GWEN_STRINGLIST *sl, const char *s, int take, int checkDouble)
Definition: stringlist.c:245
GWEN_STRINGLISTENTRY * GWEN_StringList_FirstEntry(const GWEN_STRINGLIST *sl)
Definition: stringlist.c:390
GWEN_STRINGLIST * GWEN_StringList_new(void)
Definition: stringlist.c:50
struct GWEN_STRINGLISTENTRYSTRUCT GWEN_STRINGLISTENTRY
Definition: stringlist.h:53
struct GWEN_STRINGLISTSTRUCT GWEN_STRINGLIST
Definition: stringlist.h:56
int GWEN_SyncIo_Helper_CopyFile(const char *srcPath, const char *destPath)
Definition: syncio.c:640
static void _writeProjectNameAndVersionToXml(const GWB_PROJECT *project, GWEN_XMLNODE *xmlNode)
Definition: utils.c:584
static int _readIntUntilPointOrHyphen(const char **ptrToStringPtr)
Definition: utils.c:770
int GWB_Utils_VersionStringToInt(const char *s)
Definition: utils.c:717
static int _filesChanged(const char *fileName, GWEN_STRINGLIST *slFileNameList)
Definition: utils.c:326
int GWB_Utils_WriteProjectInfoToFile(const GWB_PROJECT *project, const char *fileName)
Definition: utils.c:554
static GWB_KEYVALUEPAIR_LIST * _generateInstallList(const GWB_FILE_LIST2 *fileList, const char *initialSourceDir)
Definition: utils.c:251
void GWB_Utils_VersionToDbVar(GWEN_DB_NODE *db, const char *dbVarName, int vmajor, int vminor, int vpatchlevel, int vbuild, const char *vtag)
Definition: utils.c:794
int GWB_Utils_WriteProjectToFile(const GWB_PROJECT *project, const char *fileName)
Definition: utils.c:414
GWB_FILE_LIST2 * GWB_Utils_ReadFileList2(const char *fileName)
Definition: utils.c:71
static GWEN_STRINGLIST * _readBuildFileList(const char *fileName)
Definition: utils.c:363
GWEN_XMLNODE * GWB_Utils_ReadProjectInfoFromFile(const char *fileName)
Definition: utils.c:602
GWB_KEYVALUEPAIR_LIST * GWB_Utils_ReadInstallFileList(const char *fileName)
Definition: utils.c:202
int GWB_Utils_BuildFilesChanged(const char *fileName)
Definition: utils.c:308
int GWB_Utils_CopyFile(const char *sSrcPath, const char *sDestPath)
Definition: utils.c:460
static int _readAndStoreNextVersionPart(const char **s, GWEN_DB_NODE *db, const char *varNamePrefix, const char *varName)
Definition: utils.c:686
int GWB_Utils_VersionStringToDb(GWEN_DB_NODE *db, const char *prefix, const char *s)
Definition: utils.c:630
int GWB_Utils_WriteContextTreeToFile(const GWB_CONTEXT *ctx, const char *fileName)
Definition: utils.c:437
int GWB_Utils_WriteInstallFileList(const GWB_PROJECT *project, const char *fileName)
Definition: utils.c:152
int GWB_Utils_WriteBuildFileList(const GWENBUILD *gwenbuild, const char *fileName)
Definition: utils.c:106
int GWB_Utils_WriteProjectFileList(const GWB_PROJECT *project, const char *fileName)
Definition: utils.c:42
GWEN_XMLNODE * GWEN_XMLNode_FindFirstTag(const GWEN_XMLNODE *n, const char *tname, const char *pname, const char *pvalue)
Definition: xml.c:776
void GWEN_XMLNode_UnlinkChild(GWEN_XMLNODE *n, GWEN_XMLNODE *child)
Definition: xml.c:570
GWEN_XMLNODE * GWEN_XMLNode_new(GWEN_XMLNODE_TYPE t, const char *data)
Definition: xml.c:144
void GWEN_XMLNode_SetIntValue(GWEN_XMLNODE *n, const char *name, int value)
Definition: xml.c:940
GWEN_XMLNODE * GWEN_XMLNode_FindNextTag(const GWEN_XMLNODE *n, const char *tname, const char *pname, const char *pvalue)
Definition: xml.c:794
const char * GWEN_XMLNode_GetCharValue(const GWEN_XMLNODE *n, const char *name, const char *defValue)
Definition: xml.c:812
void GWEN_XMLNode_AddChild(GWEN_XMLNODE *n, GWEN_XMLNODE *child)
Definition: xml.c:423
GWEN_XMLNODE * GWEN_XMLNode_GetFirstData(const GWEN_XMLNODE *n)
Definition: xml.c:724
void GWEN_XMLNode_free(GWEN_XMLNODE *n)
Definition: xml.c:160
const char * GWEN_XMLNode_GetData(const GWEN_XMLNODE *n)
Definition: xml.c:370
void GWEN_XMLNode_SetCharValue(GWEN_XMLNODE *n, const char *name, const char *value)
Definition: xml.c:897
struct GWEN__XMLNODE GWEN_XMLNODE
Definition: xml.h:156
GWENHYWFAR_API int GWEN_XMLNode_WriteFile(const GWEN_XMLNODE *n, const char *fname, uint32_t flags)
Definition: xmlrw.c:583
#define GWEN_XML_FLAGS_DEFAULT
Definition: xml.h:117
GWENHYWFAR_API int GWEN_XML_ReadFile(GWEN_XMLNODE *n, const char *filepath, uint32_t flags)
Definition: xmlrw.c:1297
@ GWEN_XMLNodeTypeData
Definition: xml.h:147
@ GWEN_XMLNodeTypeTag
Definition: xml.h:145
#define GWEN_XML_FLAGS_SIMPLE
Definition: xml.h:89