TPCCLIB
Loading...
Searching...
No Matches
addvers.c
Go to the documentation of this file.
1
7/*****************************************************************************/
8#include "tpcclibConfig.h"
9/*****************************************************************************/
10#include <stdio.h>
11#include <stdlib.h>
12#include <unistd.h>
13#include <string.h>
14#include <math.h>
15/*****************************************************************************/
16#include "tpcextensions.h"
17#include "tpcift.h"
18/*****************************************************************************/
19
20/*****************************************************************************/
21static char *info[] = {
22 "Add version number to the file name, if file name does not already include",
23 "version number. Version is given in format 'n.n.n' as the first command-line",
24 "argument either directly or inside a file with keyword 'version'.",
25 "Version is added to the file name in format '_n_n_n' before any extension.",
26 " ",
27 "Usage: @P [Options] version file",
28 " ",
29 "Options:",
30 " -stdoptions", // List standard options like --help, -v, etc
31 " ",
32 "Example 1:",
33 " @P 2.13.4 patlak.exe",
34 " ",
35 "Example 2:",
36 " patlak --version > patlak.txt",
37 " iftren patlak.txt \"tpcclib version\" \"version\"",
38 " @P patlak.txt patlak.exe",
39 " ",
40 "See also: pdoc2htm, iftadd, iftren",
41 0};
42/*****************************************************************************/
43
44/*****************************************************************************/
45/* Turn on the globbing of the command line, since it is disabled by default in
46 mingw-w64 (_dowildcard=0); in MinGW32 define _CRT_glob instead, if necessary;
47 In Unix&Linux wildcard command line processing is enabled by default. */
48/*
49#undef _CRT_glob
50#define _CRT_glob -1
51*/
52int _dowildcard = -1;
53/*****************************************************************************/
54
55/*****************************************************************************/
59int main(int argc, char **argv)
60{
61 int ai, help=0, version=0, verbose=1;
62 char *cptr;
63 char exefile[FILENAME_MAX], verfile[FILENAME_MAX], vers[FILENAME_MAX];
64 int ret;
65
66
67 /*
68 * Get arguments
69 */
70 if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
71 exefile[0]=verfile[0]=vers[0]=(char)0;
72 /* Options */
73 for(ai=1; ai<argc; ai++) if(*argv[ai]=='-') {
74 if(tpcProcessStdOptions(argv[ai], &help, &version, &verbose)==0) continue;
75 //cptr=argv[ai]+1; if(*cptr=='-') cptr++; if(!*cptr) continue;
76 fprintf(stderr, "Error: invalid option '%s'.\n", argv[ai]);
77 return(1);
78 } else break; // tac name argument may start with '-'
79
80 TPCSTATUS status; statusInit(&status);
81 statusSet(&status, __func__, __FILE__, __LINE__, TPCERROR_OK);
82 status.verbose=verbose-1;
83
84 /* Print help or version? */
85 if(help==2) {tpcHtmlUsage(argv[0], info, ""); return(0);}
86 if(help) {tpcPrintUsage(argv[0], info, stdout); return(0);}
87 if(version) {tpcPrintBuild(argv[0], stdout); return(0);}
88
89 /* Process other arguments, starting from the first non-option */
90 if(ai<argc) {strlcpy(verfile, argv[ai++], FILENAME_MAX);}
91 if(ai<argc) {strlcpy(exefile, argv[ai++], FILENAME_MAX);}
92 if(ai<argc) {fprintf(stderr, "Error: too many arguments.\n"); return(1);}
93
94 /* Is something missing or wrong? */
95 if(!exefile[0]) {
96 fprintf(stderr, "Error: missing command-line argument; use option --help\n");
97 return(1);
98 }
99
100 /* In verbose mode print arguments and options */
101 if(verbose>1) {
102 printf("exefile := %s\n", exefile);
103 fflush(stdout);
104 }
105
106 /* Try to open the first argument as IFT file */
107 if(verbose>2) printf("trying to read %s\n", verfile);
108 FILE *fp=fopen(verfile, "r");
109 if(fp==NULL) {
110 if(verbose>2) printf(" ... could not open %s\n", verfile);
111 /* Assuming that version number was given directly */
112 strncpyClean(vers, verfile, FILENAME_MAX); verfile[0]=(char)0;
113 if(verbose>1) {
114 printf("version := %s\n", vers);
115 fflush(stdout);
116 }
117 } else {
118 if(verbose>1) {
119 printf("version_file := %s\n", verfile);
120 fflush(stdout);
121 }
122 /* Trying to read version from file */
123 IFT ift; iftInit(&ift);
124 ret=iftRead(&ift, fp, 1, 1, &status);
125 fclose(fp);
126 if(ret) {
127 fprintf(stderr, "Error: %s\n", errorMsg(status.error));
128 iftFree(&ift); return(2);
129 }
130 if(verbose>2) printf("list size: %d item(s)\n", ift.keyNr);
131 /* Search for the first occurrence of keyname 'version' */
132 int li=iftFindKey(&ift, "version", 0);
133 if(li<0) {
134 fprintf(stderr, "Error: file contains no key '%s'\n", "version");
135 iftFree(&ift); return(3);
136 }
137 if(verbose>3) printf("key_index := %d\n", li);
138 strncpyClean(vers, ift.item[li].value, FILENAME_MAX);
139 if(verbose>1) {
140 printf("version := %s\n", vers);
141 fflush(stdout);
142 }
143 iftFree(&ift);
144 }
145
146
147 /* Check that version number is somewhat valid */
148 ret=0;
149 {
150 int i=0;
151 while(vers[i]) {
152 if(vers[i]!='.' && isalnum(vers[i])==0) ret++;
153 if(isblank(vers[i])!=0) ret++;
154 i++;
155 }
156 }
157 if(ret>0 || strlen(vers)<1 || strlen(vers)>20) {
158 fprintf(stderr, "Error: invalid version.\n");
159 return(2);
160 }
161
162 /* Replace dots with underlines */
163 strReplaceChar(vers, '.', '_');
164 if(verbose>1) {
165 printf("version := %s\n", vers);
166 fflush(stdout);
167 }
168
169
170 /*
171 * Process the file name
172 */
173
174 /* Get the path */
175 char pathname[FILENAME_MAX];
176 strcpy(pathname, exefile);
177 filenameRmFile(pathname);
178 if(verbose>1) printf("pathname := '%s'\n", pathname);
179 /* Get the extensions */
180 char extname[FILENAME_MAX];
181 cptr=filenameGetExtensions(exefile);
182 if(cptr!=NULL) strcpy(extname, cptr); else extname[0]=(char)0;
183 if(verbose>1) printf("extname := '%s'\n", extname);
184 /* Get the file name without path and extensions */
185 char filename[FILENAME_MAX];
186 strcpy(filename, exefile);
187 filenameRmExtensions(filename);
188 filenameRmPath(filename);
189 if(verbose>1) printf("filename := '%s'\n", filename);
190 if(strlen(filename)<1) {
191 fprintf(stderr, "Error: invalid file name.\n");
192 return(2);
193 }
194 /* Check that file name does not already contain the same version string */
195 if(strstr(filename, vers)!=NULL) {
196 fprintf(stderr, "Error: file name already contains version number.\n");
197 return(4);
198 }
199 /* Construct new file name */
200 strcpy(verfile, pathname);
201 strcat(verfile, "/");
202 strcat(verfile, filename);
203 if(strlen(verfile)+strlen(vers)+strlen(extname)+2 > FILENAME_MAX) {
204 fprintf(stderr, "Error: too long file name or version.\n");
205 return(5);
206 }
207 strcat(verfile, "_");
208 strcat(verfile, vers);
209 strcat(verfile, extname);
210 if(verbose>1) {
211 printf("newfile := %s\n", verfile);
212 fflush(stdout);
213 }
214
215 /*
216 * Rename the file
217 */
218 remove(verfile); // rename() may return error if file exists (implementation-defined)
219 if(rename(exefile, verfile)!=0) {
220 fprintf(stderr, "Error: cannot rename '%s' to '%s'.\n", exefile, verfile);
221 return(9);
222 }
223 if(verbose>0) printf("%s -> %s\n", exefile, verfile);
224
225 return(0);
226}
227/*****************************************************************************/
228
229/*****************************************************************************/
void filenameRmFile(char *s)
Definition filename.c:44
char * filenameGetExtensions(const char *s)
Get all extensions of a file name.
Definition filename.c:203
void filenameRmPath(char *s)
Definition filename.c:20
void filenameRmExtensions(char *s)
Definition filename.c:89
void iftFree(IFT *ift)
Definition ift.c:37
void iftInit(IFT *ift)
Definition ift.c:21
int iftFindKey(IFT *ift, const char *key, int start_index)
Definition iftfind.c:30
int iftRead(IFT *ift, FILE *fp, int is_key_required, int is_comment_accepted, TPCSTATUS *status)
Definition iftio.c:130
int tpcProcessStdOptions(const char *s, int *print_usage, int *print_version, int *verbose_level)
Definition proginfo.c:47
int tpcHtmlUsage(const char *program, char *text[], const char *path)
Definition proginfo.c:169
void tpcPrintBuild(const char *program, FILE *fp)
Definition proginfo.c:339
void tpcPrintUsage(const char *program, char *text[], FILE *fp)
Definition proginfo.c:114
void statusInit(TPCSTATUS *s)
Definition statusmsg.c:104
char * errorMsg(tpcerror e)
Definition statusmsg.c:68
void statusSet(TPCSTATUS *s, const char *func, const char *srcfile, int srcline, tpcerror error)
Definition statusmsg.c:142
void strReplaceChar(char *s, char c1, char c2)
Definition stringext.c:134
size_t strlcpy(char *dst, const char *src, size_t dstsize)
Definition stringext.c:632
int strncpyClean(char *s1, const char *s2, int maxlen)
Definition stringext.c:321
char * value
Definition tpcift.h:37
Definition tpcift.h:43
IFT_ITEM * item
Definition tpcift.h:57
int keyNr
Definition tpcift.h:47
int verbose
Verbose level, used by statusPrint() etc.
tpcerror error
Error code.
Header file for library libtpcextensions.
@ TPCERROR_OK
No error.
Header file for library libtpcift.