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 
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 
39 
40 
41 
42 int 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 
52  xmlNode=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, "root");
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 
71 GWB_FILE_LIST2 *GWB_Utils_ReadFileList2(const char *fileName)
72 {
73  GWEN_XMLNODE *xmlRoot;
74  GWEN_XMLNODE *xmlFileList;
75  int rv;
76 
77  xmlRoot=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, "root");
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 
106 int 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");
131  xmlFileName=GWEN_XMLNode_new(GWEN_XMLNodeTypeData, s);
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 
152 int 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 
202 GWB_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 
251 GWB_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 
272  s=GWB_File_GetInstallPath(file);
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 
308 int 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 
326 int _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 
363 GWEN_STRINGLIST *_readBuildFileList(const char *fileName)
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 
382  sl=GWEN_StringList_new();
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 
414 int 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 
437 int 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 
460 int 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 
554 int 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;
587  s=GWB_Project_GetProjectName(project);
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 
630 int 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 
686 int _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 
770 int _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 
794 void 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 
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
int GWB_Utils_WriteInstallFileList(const GWB_PROJECT *project, const char *fileName)
Definition: utils.c:152
#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:308
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:1297
void GWB_File_List2_ReadXml(GWEN_XMLNODE *xmlNode, const char *groupName, GWB_FILE_LIST2 *destFileList)
Definition: file.c:693
struct GWB_PROJECT GWB_PROJECT
Definition: project.h:14
int GWB_Utils_VersionStringToInt(const char *s)
Definition: utils.c:717
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:602
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:650
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:71
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
#define GWEN_DIR_FLAGS_PUBLIC_NAME
Definition: directory.h:61
GWB_KEYVALUEPAIR_LIST * GWB_Utils_ReadInstallFileList(const char *fileName)
Definition: utils.c:202
int GWB_Utils_WriteProjectToFile(const GWB_PROJECT *project, const char *fileName)
Definition: utils.c:414
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:554
#define DBG_DEBUG(dbg_logger, format, args...)
Definition: debug.h:214
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:794
int GWEN_Buffer_AppendArgs(GWEN_BUFFER *bf, const char *fmt,...)
Definition: buffer.c:1084
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:251
GWENHYWFAR_API int GWEN_XMLNode_WriteFile(const GWEN_XMLNODE *n, const char *fname, uint32_t flags)
Definition: xmlrw.c:583
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:460
static int _readIntUntilPointOrHyphen(const char **ptrToStringPtr)
Definition: utils.c:770
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
#define DBG_ERROR(dbg_logger, format, args...)
Definition: debug.h:97
void GWB_File_List2_WriteXml(const GWB_FILE_LIST2 *fileList, GWEN_XMLNODE *xmlNode, const char *groupName)
Definition: file.c:670
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:437
int GWB_Project_GetVersionMinor(const GWB_PROJECT *project)
Definition: project.c:115
time_t GWBUILD_GetModificationTimeOfFile(const char *filename)
Definition: gwenbuild.c:885
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:473
uint32_t GWB_File_GetFlags(const GWB_FILE *f)
Definition: file.c:99
#define DBG_INFO(dbg_logger, format, args...)
Definition: debug.h:181
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:630
int GWB_Utils_WriteProjectFileList(const GWB_PROJECT *project, const char *fileName)
Definition: utils.c:42
int GWEN_DB_SetIntValue(GWEN_DB_NODE *n, uint32_t flags, const char *path, int val)
Definition: db.c:1202
static void _writeProjectNameAndVersionToXml(const GWB_PROJECT *project, GWEN_XMLNODE *xmlNode)
Definition: utils.c:584
static int _readAndStoreNextVersionPart(const char **s, GWEN_DB_NODE *db, const char *varNamePrefix, const char *varName)
Definition: utils.c:686
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:363
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:989
int GWB_Utils_WriteBuildFileList(const GWENBUILD *gwenbuild, const char *fileName)
Definition: utils.c:106
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:326