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