8#include "tpcclibConfig.h"
22int html_replace_mode=0;
24int html_case_sensitive=0;
33static char *info[] = {
34 "Program for searching HTML and XHTML code in a specified file or in every",
35 "file with extensions *.htm, *.html and *.xhtml that are found under the",
36 "specified path. Optionally, the (X)HTML code fragment can be changed to",
37 "the given text in every place where it is found.",
39 "Usage: @P [options] path_or_file search_text",
42 " -replace <Substitute text>",
43 " Search text is replaced by specified text in every instance;",
44 " substitute must not contain certain special characters like '&'",
45 " -replace-from-file <Filename>",
46 " Search text is replaced in every instance by the contents of",
47 " the specified ASCII text file, including new line characters;",
48 " text length must not exceed 2047 characters",
50 " Search is case-sensitive. By default, upper-and lowercase letters",
51 " are considered equal",
55 "Command for finding out if and where the specified HTML file",
56 "contains HTML code fragment '<a href=':",
57 " @P webpage.html \"<a href=\"",
60 "Command for replacing a web address with another in all HTML",
61 "files which can be found in the current directory and below it:",
62 " @P -replace www.new.fi . www.old.fi",
64 "Alternatively, in bash you can search a string in files using grep",
65 "from files with certain extension, for example:",
66 " grep \"string_to_search\" . -R --include \"*.c\" ",
68 "Keywords: HTML, tools",
100 int c, i, n=0, len, replen=0, line=1, column=0, last_c=0, found_nr=0;
101 char tempfile[FILENAME_MAX], *buf;
105 if(htmlfile==NULL || searchstring==NULL)
return(-1);
106 if(strlen(htmlfile)<1)
return(-1);
107 if(verbose>1) fprintf(stdout,
"html_find(%s, %s, %s)\n",
108 htmlfile, searchstring, replacestring);
111 len=strlen(searchstring);
113 if(verbose>=0) fprintf(stdout,
"%s (1,1)\n", htmlfile);
118 if(html_replace_mode==1) {
119 replen=strlen(replacestring);
120 buf=malloc(replen+128);
if(buf==NULL)
return(-2);
128 if((fpi=fopen(htmlfile,
"r"))==NULL) {
129 if(html_replace_mode==1) free(buf);
133 if(html_replace_mode==1) {
134 strcpy(tempfile, htmlfile); strcat(tempfile,
".bak");
135 if((fpo=fopen(tempfile,
"w"))==NULL) {
136 fclose(fpi); free(buf);
return(-4);}
139 while((c=fgetc(fpi))!=EOF) {
140 if(html_replace_mode==1) buf[n]=c;
142 if(c==
'\n' || c==
'\r') {
143 if(html_replace_mode==1 && n==0) {fputc(c, fpo);}
145 if((c==
'\n'&&last_c!=
'\r') || (c==
'\r'&&last_c!=
'\n')) line++;
150 if(html_case_sensitive==0) c=toupper(c);
152 if(c==searchstring[n]) {
156 fprintf(stdout,
"%s (%d,%d)\n", htmlfile, line, column);
158 if(html_replace_mode==1) {
161 if(fputc(replacestring[i++], fpo)==EOF) {
162 fclose(fpi); fclose(fpo); remove(tempfile); free(buf);
return(-11);
167 if(html_replace_mode==1) {
169 while(i<=n)
if(fputc(buf[i++], fpo)==EOF) {
170 fclose(fpi); fclose(fpo); remove(tempfile); free(buf);
return(-12);}
178 if(html_replace_mode==1) {
179 fclose(fpo); free(buf);
183 remove(htmlfile); rename(tempfile, htmlfile);
184 if(verbose>0) printf(
"%d '%s'(s) substituted with '%s' in %s\n",
185 found_nr, searchstring, replacestring, htmlfile);
198int html_recursive_find(
212 char tempname[FILENAME_MAX];
215 if(verbose>1) printf(
"html_recursive_find(%s, %s, %s)\n",
216 searchpath, searchstring, replacestring);
218 if(searchpath==NULL || searchstring==NULL)
return(1);
219 if(strlen(searchpath)<1)
return(1);
222 stat(searchpath, &fst);
223 if(S_ISDIR(fst.st_mode)) {
224 if(verbose>3) printf(
" %s is directory\n", searchpath);
226 dp=opendir(searchpath);
if(dp==NULL)
return(2);
228 while((de=readdir(dp))!=NULL) {
229 if(verbose>5) printf(
"d_name='%s'\n", de->d_name);
230 if(de->d_name[0]==
'.')
continue;
232 sprintf(tempname,
"%s/%s", searchpath, de->d_name);
233 if(verbose>3) printf(
"name='%s'\n", tempname);
235 ret=html_recursive_find(tempname, searchstring, replacestring, verbose);
236 if(ret) {closedir(dp);
return(ret);}
241 n=strlen(searchpath);
242 if((n>=5 && strcasecmp(searchpath+n-4,
".htm")==0) ||
243 (n>=6 && strcasecmp(searchpath+n-5,
".html")==0) ||
244 (n>=7 && strcasecmp(searchpath+n-6,
".xhtml")==0)) {
246 ret=html_find(searchpath, searchstring, replacestring, verbose);
247 if(verbose>8) printf(
" html_find(%s, %s)=%d\n",
248 tempname, searchstring, ret);
250 html_file_nr++; html_find_nr+=ret;
262int main(
int argc,
char *argv[])
264 int ai, help=0, version=0, verbose=1;
268 char searchpath[FILENAME_MAX], searchstring[1024], replacestring[2048];
274 if(argc==1) {
tpcPrintUsage(argv[0], info, stderr);
return(1);}
275 searchpath[0]=searchstring[0]=replacestring[0]=(char)0;
277 for(ai=1; ai<argc; ai++)
if(*argv[ai]==
'-') {
280 if(strcasecmp(cptr,
"CASE-INSENSITIVE")==0) {
281 html_case_sensitive=0;
continue;
282 }
else if(strncasecmp(cptr,
"CASE-SENSITIVE", 4)==0) {
283 html_case_sensitive=1;
continue;
284 }
else if(strcasecmp(cptr,
"REPLACE")==0) {
285 html_replace_mode=1; ai++;
286 if(ai<argc) {strcpy(replacestring, argv[ai]);
continue;}
287 }
else if(strcasecmp(cptr,
"REPLACE-FROM-FILE")==0) {
288 html_replace_mode=1; ai++;
290 FILE *fp;
int c; fp=fopen(argv[ai],
"r");
292 if(verbose>1) printf(
"reading %s\n", argv[ai]);
294 while(c!=EOF && i<2047) {replacestring[i++]=c; c=fgetc(fp);}
295 replacestring[i]=(char)0;
297 fprintf(stderr,
"Error: too much contents in %s\n.\n", argv[ai]);
298 fclose(fp);
return(1);
300 fclose(fp);
if(i>0)
continue;
304 fprintf(stderr,
"Error: invalid option '%s'\n", argv[ai]);
309 for(; ai<argc; ai++) {
311 strcpy(searchpath, argv[ai]);
continue;
312 }
else if(!searchstring[0]) {
313 strcpy(searchstring, argv[ai]);
continue;
315 fprintf(stderr,
"Error: invalid argument '%s'.\n", argv[ai]);
319 if(help==2) {
tpcHtmlUsage(argv[0], info,
"");
return(0);}
323 if(!searchstring[0]) {
325 if(html_replace_mode && !replacestring[0]) {
330 printf(
"searchpath := %s\n", searchpath);
331 printf(
"searchstring := %s\n", searchstring);
332 printf(
"replacestring := %s\n", replacestring);
333 printf(
"html_replace_mode := %d\n", html_replace_mode);
334 printf(
"html_case_sensitive := %d\n", html_case_sensitive);
342 if(html_case_sensitive==0)
343 for(i=0; i<strlen(searchstring); i++)
344 searchstring[i]=(
char)toupper((
int)searchstring[i]);
349 ret=html_recursive_find(searchpath, searchstring, replacestring, verbose);
351 fprintf(stderr,
"Error in searching HTML files (%d).\n", ret);
355 fprintf(stdout,
"Search text was found %d times in %d file(s).\n",
356 html_find_nr, html_file_nr);
358 fprintf(stdout,
"Search text was not found.\n");
Header file for libtpcmisc.
int tpcProcessStdOptions(const char *s, int *print_usage, int *print_version, int *verbose_level)
int tpcHtmlUsage(const char *program, char *text[], const char *path)
void tpcPrintBuild(const char *program, FILE *fp)
void tpcPrintUsage(const char *program, char *text[], FILE *fp)