"Fossies" - the Fresh Open Source Software Archive 
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
1 /* int.c - Initialisation code for replace command
2 (C) Richard K. Lloyd 2001-2004
3 */
4
5 #define Extern
6 #include "replace.h"
7
8 /* This next string gets output when you do a "what replace" in HP-UX */
9 static char ident[] = "@(#)replace " REPLACE_VERSION " (C) Richard K. Lloyd " REPLACE_YEAR;
10
11 #ifdef __STDC__
12 void set_temp_file(char *tfile)
13 #else
14 void set_temp_file(tfile)
15 char *tfile;
16 #endif
17 {
18 /* The file passed to this routine should be unlinked in the tidy_up()
19 routine. Passing "" as a file clears this and won't unlink during
20 tidy_up(); */
21 (void)strcpy(tempfile_cleanup,tfile);
22 }
23
24 void tidy_up(P(void))
25 {
26 /* I don't actually have to include this routine since UNIX does it for me
27 when the program exits, but let's be careful anyway - you never know,
28 it might be a library one day :-) */
29
30 size_t f;
31
32 for (f=1;f<=numstrs;f++)
33 {
34 if (oldstr[f]!=(char *)NULL) free((MALLOCPTR)oldstr[f]);
35 if (newstr[f]!=(char *)NULL) free((MALLOCPTR)newstr[f]);
36 }
37 for (f=1;f<=suffixes;f++)
38 if (sufflist[f]!=(char *)NULL) free((MALLOCPTR)sufflist[f]);
39 if (binchunkptr!=(char *)NULL) free((MALLOCPTR)binchunkptr);
40 if (thestring!=(char *)NULL) free((MALLOCPTR)thestring);
41
42 /* Remove any temp file that was being worked on at the time */
43 if (tempfile_cleanup[0]) (void)unlink(tempfile_cleanup);
44 }
45
46 #ifdef __STDC__
47 void tidy_up_handler(int signum)
48 #else
49 void tidy_up_handler(signum)
50 int signum;
51 #endif
52 {
53 /* Handle signal appropriately and then exit the program */
54 (void)signal(signum,SIG_DFL); /* Reset handler back to default */
55 tidy_up();
56 exit(EXIT_FAILURE);
57 }
58
59 void init_vars(P(void))
60 {
61 /* Initialise global variables */
62
63 set_temp_file(""); /* No temporary file to clean up yet */
64 numstrs=0; /* No strings yet */
65 numfilereps=0; /* Number of files that had their strings replaced */
66 numfiles=0; /* Total number of files scanned */
67 numreps=0; /* Total number of replacements */
68
69 /* Default settings if no qualifiers supplied */
70 sensitive=0; /* Case-insensitive */
71 word=1; /* Match words only, not sub-strings */
72 force=0; /* Don't force it - keep .cln version */
73 padit=0; /* Don't pad new string with trailing spaces */
74 prepadit=0; /* Don't pad new string with leading spaces */
75 verbose=0; /* Not verbose */
76 startcol=1; /* Start replacing from column 1 */
77 startline=1; /* Start replacing from line 1 */
78 recursive=0; /* Don't recurse */
79 suffixes=0; /* No suffixes yet */
80 minsuff=BUFSIZ; /* Minimum length of a suffix */
81 prompt=0; /* Don't prompt yet */
82 fake=0; /* Don't "fake" the replacements */
83 binary=0; /* Not forcing binary replacements */
84 ascii=0; /* Not forcing text replacements */
85 hex=0; /* Not hex strings */
86 maxreplines=0; /* Replace in any number of lines */
87 maxtimes=0; /* Replace string any number of times in a single line */
88 zeroterm=0; /* Don't zero-terminate */
89 binchunkptr=(char *)NULL; binchunksize=0; /* No binary chunk yet */
90 thestring=(char *)NULL; thestringsize=0; /* No text string yet */
91 newline=(char *)NULL; newlinesize=0; /* No newstr output buffer yet */
92 retainstamp=0; /* Don't keep the timestamp of the original file */
93 followsoftlinks=0; /* Ignore soft-links if specified as filenames */
94 autodetect=1; /* Auto-detect if binary or text */
95 autobinsize=0; /* Didn't read any bytes for auto-detect yet */
96
97 /* Now set up signals to run the tidy_up_handler() routine */
98 (void)signal(SIGINT,tidy_up_handler);
99 }
100
101 #ifdef __STDC__
102 void leave(char *errmess)
103 #else
104 void leave(errmess)
105 char *errmess;
106 #endif
107 {
108 /* Something wrong, so leave, displaying an error message if non-null */
109 tidy_up();
110 if (errmess[0]) (void)fprintf(stderr,"%s: FATAL - %s\n",progname,errmess);
111 exit(EXIT_FAILURE);
112 }
113
114 #ifdef __STDC__
115 static void add_suffix(char *sfx)
116 #else
117 static void add_suffix(sfx)
118 char *sfx;
119 #endif
120 {
121 /* New suffix to add to the list */
122 if (suffixes<MAXSTRS)
123 {
124 size_t sxlen=strlen(sfx);
125 if (sxlen<minsuff) minsuff=sxlen;
126 if ((sufflist[++suffixes]=(char *)malloc(sxlen+1))==(char *)NULL)
127 leave("Can't allocate memory for new suffix");
128 (void)strcpy(sufflist[suffixes],sfx);
129 }
130 else
131 (void)fprintf(stderr,"WARNING: Already at limit of %d suffixes - ignored %s suffix\n",MAXSTRS,sfx);
132 }
133
134 #ifdef __STDC__
135 static void padline(char *pstr)
136 #else
137 static void padline(pstr)
138 char *pstr;
139 #endif
140 {
141 /* Pad syntax options to line up after the "Syntax: " string */
142 (void)fprintf(stderr,"%*s%s\n",(int)strlen(progname)+9,"",pstr);
143 }
144
145 static void usage(P(void))
146 /* Tell the user what to type next time... */
147 {
148 (void)fprintf(stderr,"%s - The sane person's alternative to sed\n\n",&ident[4]);
149 (void)fprintf(stderr,"Syntax: %s [-?] [-A] [-b] [-c startcol] [-d tempdir] [-e] [-f]\n",progname);
150 padline("[-h] [-i] [-L] [-l linenum] [-m maxreplines] [-n] [-P] [-p]");
151 padline("[-r|R] [-s] [-T] [-t maxtimes] [-u backupsuffix] [-v]");
152 padline("[-w] [-x suffix [-x...]] [-z]");
153 padline("old_str new_str [-a old_str new_str...] [filename...]\n");
154 (void)fprintf(stderr,"-? displays this syntax message.\n");
155 (void)fprintf(stderr,"-A forces the program to assume all files are text files. Normally, the first\n");
156 (void)fprintf(stderr," %d bytes are examined to auto-determine if a file is text or binary.\n",MAX_BIN_BYTES);
157 (void)fprintf(stderr," This option is deprecated and may be changed or removed in a future release.\n");
158 (void)fprintf(stderr,"-a allows extra pairs of strings to be replaced in order.\n");
159 (void)fprintf(stderr,"-b forces the program to assume all files are binary files.\n");
160 (void)fprintf(stderr,"-c startcol starts the string replace from column 'startcol' rather than the\n");
161 (void)fprintf(stderr," first column.\n");
162 (void)fprintf(stderr,"-d specifies the temporary directory for storing modified files. If not\n");
163 (void)fprintf(stderr," supplied, the default directory is $TMPDIR or, if that isn't set, %s.\n",DEF_TMP_DIR);
164 (void)fprintf(stderr,"-e makes search case-sensitive. new_str exactly replaces old_str\n");
165 (void)fprintf(stderr," with no case-adjustment to new_str.\n");
166 (void)fprintf(stderr,"-f forces the update of files without any %s backup.\n",backupsuff);
167 (void)fprintf(stderr,"-h indicates that replacement pairs are binary hex data.\n");
168 (void)fprintf(stderr,"-i interactively prompts the user to confirm if they want strings replaced in\n");
169 (void)fprintf(stderr," next file. Specifying -i -i switches to prompting for each replacement.\n");
170 (void)fprintf(stderr,"-L follows soft-links specified on the command line.\n");
171 (void)fprintf(stderr,"-l linenum starts the string replacement from line 'linenum' rather than the\n");
172 (void)fprintf(stderr," first line.\n");
173 (void)fprintf(stderr,"-m maxreplines specifies the maximum number of lines in a file that should\n");
174 (void)fprintf(stderr," have string replacements.\n");
175 (void)fprintf(stderr,"-n displays what strings would be replaced without actually replacing them.\n");
176 (void)fprintf(stderr," It also switches on verbose mode.\n");
177 (void)fprintf(stderr,"-P pre-pads new_str with leading spaces if it is shorter than old_str.\n");
178 (void)fprintf(stderr,"-p pads new_str with trailing spaces if it is shorter than old_str.\n");
179 (void)fprintf(stderr,"-r or -R recurses down the current directory tree (if no filenames are given),\n");
180 (void)fprintf(stderr," replacing strings in all files found. Use -x to narrow the recursion.\n");
181 (void)fprintf(stderr,"-s relaxes the condition that old_str has to match a 'word' i.e. it replaces\n");
182 (void)fprintf(stderr," old_str even if it is a substring of a 'word'.\n");
183 (void)fprintf(stderr,"-T retains the timestamps of the original unmodified files.\n");
184 (void)fprintf(stderr,"-t maxtimes states the maximum number of times a string can be replaced\n");
185 (void)fprintf(stderr," in any single line of a file.\n");
186 (void)fprintf(stderr,"-u backupsuffix specifies the backup suffix for the unmodified file.\n");
187 (void)fprintf(stderr,"-v increments (switches on) verbose mode, reporting a summary of replacements\n");
188 (void)fprintf(stderr," if specified once and all replacements if specified twice (i.e. -vv).\n");
189 (void)fprintf(stderr,"-w recursively replaces strings in all Web-related source files in the current\n");
190 (void)fprintf(stderr," directory tree. Equivalent to \"-r -x .html -x .htm -x .asp -x .js -x .css\n");
191 (void)fprintf(stderr," -x .xml -x .xhtml -x .shtml -x .jsp -x .php -x .php3 -x .php4 -x .pl\".\n");
192 (void)fprintf(stderr,"-x suffix specifies a case-insensitive filename suffix to look for when\n");
193 (void)fprintf(stderr," recursing. Multiple -x params can be supplied and have an \"or\" meaning.\n");
194 (void)fprintf(stderr,"-z Zero-terminate any binary replacement string.\n");
195 leave("");
196 }
197
198 #ifdef __STDC__
199 void get_options(int argc,char **argv)
200 #else
201 void get_options(argc,argv)
202 int argc;
203 char **argv;
204 #endif
205 /* Parse the standard qualifiers */
206 {
207 int param,looping=1;
208 size_t alloclen,newtmp,oldtmp;
209 char *tmpdirptr=getenv("TMPDIR");
210
211 (void)strcpy(progname,basename_path(argv[0])); /* Get `basename $0` */
212 (void)strcpy(backupsuff,DEF_BACKUP_SUFFIX);
213 if (tmpdirptr==(char *)NULL)
214 (void)strcpy(tmpdir,DEF_TMP_DIR);
215 else (void)strcpy(tmpdir,tmpdirptr);
216
217 while ((param = getopt(argc,argv,"+Abc:d:efhiLl:m:nPprRsTt:u:vwx:z?")) != EOF)
218 {
219 switch (param)
220 {
221 case '?': usage(); /* Bad option */
222 break;
223 case 'A': ascii=1;
224 (void)fprintf(stderr,"WARNING: The current behaviour of -A is deprecated - this option may change\n");
225 (void)fprintf(stderr," its functionality or be removed in a future release.\n");
226 break;
227 case 'b': binary=1;
228 break;
229 case 'c': startcol=(size_t)atoi(optarg);
230 break;
231 case 'd': (void)strcpy(tmpdir,optarg);
232 break;
233 case 'e': sensitive=1;
234 break;
235 case 'f': force=1;
236 break;
237 case 'h': hex=1; binary=1; sensitive=1;
238 break;
239 case 'i': if (prompt<2) prompt++;
240 break;
241 case 'L': followsoftlinks=1;
242 break;
243 case 'l': startline=atoi(optarg);
244 break;
245 case 'm': maxreplines=atoi(optarg);
246 break;
247 case 'n': if (fake<2) fake++;
248 break;
249 case 'P': prepadit=1;
250 break;
251 case 'p': padit=1;
252 break;
253 case 'R':
254 case 'r': recursive=1;
255 break;
256 case 's': word=0;
257 break;
258 case 'T': retainstamp=1;
259 break;
260 case 't': maxtimes=atoi(optarg);
261 break;
262 case 'u': (void)strcpy(backupsuff,optarg);
263 break;
264 case 'v': if (verbose<2) verbose++;
265 break;
266 case 'w': recursive=1;
267 add_suffix(".html");
268 add_suffix(".htm");
269 add_suffix(".asp");
270 add_suffix(".js");
271 add_suffix(".css");
272 add_suffix(".xml");
273 add_suffix(".xhtml");
274 add_suffix(".shtml");
275 add_suffix(".jsp");
276 add_suffix(".php");
277 add_suffix(".php3");
278 add_suffix(".php4");
279 add_suffix(".pl");
280 break;
281 case 'x': add_suffix(optarg);
282 break;
283 case 'z': zeroterm=1;
284 break;
285 }
286 }
287
288 /* Adjust verbosity level */
289 if (verbose<prompt) verbose=prompt;
290 if (verbose<fake) verbose=fake;
291
292 if (padit && prepadit) leave("You can't specify both -P and -p: they are mutually exclusive");
293
294 if (ascii && binary) leave("You can't specify both -A and -b: they are mutally exclusive");
295 if (ascii || binary) autodetect=0;
296
297 if (binary)
298 {
299 if (hex || padit || prepadit) zeroterm=0;
300 startcol=1; startline=1;
301 maxreplines=0; word=0;
302 }
303 else
304 if (zeroterm) leave("You must additionally specify -b when using -z");
305
306 sufflen=strlen(backupsuff);
307
308 while (looping)
309 {
310 if (optind+2>argc) usage();
311
312 oldtmp=strlen(argv[optind]);
313 if (!oldtmp && binary) leave("Old string must be non-null");
314
315 if (hex)
316 {
317 int hptr=2;
318 size_t hlp;
319 int hval;
320
321 if (oldtmp%2) hptr--;
322 oldtmp=(oldtmp+1)/2;
323 if ((oldstr[++numstrs]=(char *)malloc((MALLOCPAR)oldtmp))==(char *)NULL)
324 leave("Can't allocate memory for old hex string");
325 for (hlp=0;hlp<oldtmp;hlp++)
326 {
327 char oarg=argv[optind][hptr];
328 argv[optind][hptr]='\0';
329 hval=0;
330 (void)sscanf(&argv[optind][hptr-1-(hptr>1)],"%x",&hval);
331 oldstr[numstrs][hlp]=(char)hval;
332 argv[optind][hptr]=oarg;
333 hptr+=2;
334 }
335 }
336 else
337 {
338 if ((oldstr[++numstrs]=(char *)malloc((MALLOCPAR)(oldtmp+1)))==(char *)NULL)
339 leave("Can't allocate memory for old string");
340 (void)strcpy(oldstr[numstrs],argv[optind]);
341 }
342 oldstrlen[numstrs]=oldtmp;
343
344 newtmp=strlen(argv[++optind]);
345 if (!newtmp && binary) leave("New string must be non-null");
346
347 if ((prepadit || padit) && newtmp<oldtmp && !hex) alloclen=oldtmp; else alloclen=newtmp;
348
349 if (hex)
350 {
351 int hptr=2;
352 int hval;
353 size_t hlp;
354
355 if (newtmp%2) hptr--;
356 newtmp=(newtmp+1)/2;
357 alloclen=newtmp;
358 if ((newstr[numstrs]=(char *)malloc((MALLOCPAR)alloclen))==(char *)NULL)
359 leave("Can't allocate memory for new hex string");
360 for (hlp=0;hlp<newtmp;hlp++)
361 {
362 char oarg=argv[optind][hptr];
363 argv[optind][hptr]='\0';
364 hval=0;
365 (void)sscanf(&argv[optind][hptr-1-(hptr>1)],"%x",&hval);
366 newstr[numstrs][hlp]=(char)hval;
367 argv[optind][hptr]=oarg;
368 hptr+=2;
369 }
370 }
371 else
372 {
373 if ((newstr[numstrs]=(char *)malloc((MALLOCPAR)(alloclen+1)))==(char *)NULL)
374 leave("Can't allocate memory for new string");
375 (void)strcpy(newstr[numstrs],argv[optind]);
376 if (padit)
377 {
378 while (newtmp<oldtmp) { newstr[numstrs][newtmp++]=' '; }
379 newstr[numstrs][newtmp]='\0';
380 }
381 else
382 if (prepadit && newtmp<oldtmp)
383 {
384 size_t cp,sdf=oldtmp-newtmp;
385 for (cp=oldtmp-1;cp>=sdf;cp--)
386 { newstr[numstrs][cp]=newstr[numstrs][cp-sdf]; }
387 for (cp=0;cp<sdf;cp++) newstr[numstrs][cp]=' ';
388 newstr[numstrs][newtmp=oldtmp]='\0';
389 }
390 }
391 newstrlen[numstrs]=alloclen+zeroterm;
392
393 if (binary && newtmp>oldtmp) leave("New binary string mustn't be larger than old binary string");
394
395 if (zeroterm && newtmp>=oldtmp) leave("New binary string must be smaller than old binary string if -z used");
396
397 if (hex)
398 {
399 if (newtmp==oldtmp && !memcmp((void *)oldstr[numstrs],(void *)newstr[numstrs],oldtmp))
400 leave("Old and new hex strings must be different");
401 }
402 else
403 if ((sensitive && !strcmp(oldstr[numstrs],newstr[numstrs])) ||
404 (!sensitive && !strcasecmp(oldstr[numstrs],newstr[numstrs])))
405 leave("Old and new strings must be different");
406
407 /* Yes, I could short-cut this, but some lints complain if I do */
408 looping=(++optind<argc);
409 if (looping)
410 {
411 looping=(!strcmp(argv[optind],"-a") && numstrs<MAXSTRS);
412 if (looping) optind++;
413 }
414 }
415
416 if (suffixes && !recursive) leave("You must use -x in conjunction with -r or -w");
417
418 if (verbose && !binary)
419 (void)fprintf(stderr,"Text file replacements start from column %d on each line and from line %d onwards\n",(int)startcol,startline);
420 startcol--; /* Adjust start column to match char array index */
421 }