string.c
上传用户:qin5330
上传日期:2007-01-05
资源大小:114k
文件大小:14k
源码类别:

搜索引擎

开发平台:

Perl

  1. /*
  2. ** Copyright (C) 1995, 1996, 1997, 1998 Hewlett-Packard Company
  3. ** Originally by Kevin Hughes, kev@kevcom.com, 3/11/94
  4. **
  5. ** This program and library is free software; you can redistribute it and/or
  6. ** modify it under the terms of the GNU (Library) General Public License
  7. ** as published by the Free Software Foundation; either version 2
  8. ** of the License, or any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU (Library) General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU (Library) General Public License
  16. ** along with this program; if not, write to the Free Software
  17. ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18. **---------------------------------------------------------
  19. ** ** ** PATCHED 5/13/96, CJC
  20. ** Added MatchAndChange for regex in replace rule G.Hill 2/10/98
  21. */
  22. #include "swish.h"
  23. #include "string.h"
  24. #include "mem.h"
  25. /* My own case-insensitive strstr().
  26. */
  27. char *lstrstr(s, t)
  28. char *s;
  29. char *t;
  30. {
  31. int i, j, k, l;
  32. for (i = 0; s[i]; i++) {
  33. for (j = 0, l = k = i; s[k] && t[j] &&
  34. tolower(s[k]) == tolower(t[j]); j++, k++)
  35. ;
  36. if (t[j] == '')
  37. return s + l;
  38. }
  39. return NULL;
  40. }
  41. /* Another case insensitive comparison by M.Gaulin*/
  42. int ourstricmp(const char* s1, const char* s2)
  43. {
  44.         while (*s1 && *s2)
  45.   {
  46.                 char c1 = *s1++;
  47.                 char c2 = *s2++;
  48.                 int diff = (tolower(c1) - tolower(c2));
  49.                 if (diff)
  50.                         return diff;
  51.       }
  52.         return (*s1 - *s2);
  53.       }
  54. /* Gets the next word in a line. If the word's in quotes,
  55. ** include blank spaces in the word or phrase.
  56. */
  57. char *getword(line, skiplen)
  58. char *line;
  59. int *skiplen;
  60. {
  61. int i, inquotes;
  62. char *start;
  63. static char word[MAXSTRLEN];
  64. start = line;
  65. if (!(*line))
  66. return "";
  67. while (isspace(*line))
  68. line++;
  69. if (!(*line))
  70. return "";
  71. if (*line == '"') {
  72. inquotes = 1;
  73. line++;
  74. }
  75. else
  76. inquotes = 0;
  77. for (i = 0; *line && i < MAXSTRLEN &&
  78.         ((inquotes) ? (*line != '"') : (!isspace(*line))); line++)
  79. word[i++] = *line;
  80. word[i] = '';
  81. if (!(*line))
  82. return "";
  83. if (*line == '"')
  84. line++;
  85. *skiplen = line - start;
  86. return word;
  87. }
  88. /* Gets the value of a variable in a line of the configuration file.
  89. ** Basically, anything in quotes or an argument to a variable.
  90. */
  91. char *getconfvalue(line, var, value)
  92. char *line;
  93. char *var;
  94. char *value;
  95. {
  96. int i;
  97. char *c;
  98. static char tmpvalue[MAXSTRLEN];
  99. if ((c = (char *) lstrstr(line, var)) != NULL) {
  100. if (c != line)
  101. return NULL;
  102. c += strlen(var);
  103. while (isspace(*c) || *c == '"')
  104. c++;
  105. if (*c == '')
  106. return NULL;
  107. for (i = 0; *c != '' && *c != '"' && *c != 'n' &&
  108. i < MAXSTRLEN; c++)
  109. tmpvalue[i++] = *c;
  110. tmpvalue[i] = '';
  111. strcpy(value, tmpvalue);
  112. return tmpvalue;
  113. }
  114. else
  115. return NULL;
  116. }
  117. /* Extracts anything in <title> tags from an HTML file and returns it.
  118. ** Otherwise, only the file name without its path is returned.
  119. */
  120. char *parsetitle(filename, alttitle)
  121. char *filename;
  122. char *alttitle;
  123. {
  124. register int c, d;
  125. register char *p;
  126. char *tag;
  127. static char title[MAXTITLELEN], shorttitle[MAXTITLELEN];
  128. int i, j, lines, status, tagbuflen, totaltaglen;
  129. FILE *fp;
  130. tag = (char *) emalloc(1);
  131. tag[0] = '';
  132. lines = status = 0;
  133. p = title;
  134. *p = '';
  135. if (strrchr(alttitle, '/'))
  136. strcpy(shorttitle, strrchr(alttitle, '/') + 1);
  137. else
  138. strcpy(shorttitle, alttitle);
  139. fp = fopen(filename, "r");
  140. if (fp == NULL) {
  141. free(tag);
  142. return shorttitle;
  143. }
  144. for (; lines < TITLETOPLINES ; ) {
  145. c = getc(fp);
  146. if (c == 'n')
  147. lines++;
  148. if (feof(fp)) {
  149. fclose(fp);
  150. free(tag);
  151. return shorttitle;
  152. }
  153. switch(c) {
  154. case '<':
  155. free(tag);
  156. tag = (char *) emalloc(MAXSTRLEN);
  157. tag[0] = '';
  158. tagbuflen = totaltaglen = 0;
  159. tag[totaltaglen++] = '<';
  160. tagbuflen++;
  161. status = TI_OPEN;
  162. while (1) {
  163. d = getc(fp);
  164. if (d == EOF) {
  165. fclose(fp);
  166. free(tag);
  167. return shorttitle;
  168. }
  169. else if (d == '>') {
  170. tag[totaltaglen] = '';
  171. tag = (char *) erealloc(tag,
  172. totaltaglen + MAXSTRLEN);
  173. sprintf(tag, "%s%c", tag, '>');
  174. break;
  175. }
  176. tag[totaltaglen++] = d;
  177. tagbuflen++;
  178. if (tagbuflen >= MAXSTRLEN) {
  179. tag = (char *) erealloc(tag,
  180. totaltaglen + MAXSTRLEN);
  181. tagbuflen = 0;
  182. }
  183. }
  184. if (lstrstr(tag, "</title>")) {
  185. status = TI_CLOSE;
  186. *p = '';
  187. fclose(fp);
  188. for (i = 0; title[i]; i++)
  189. if (title[i] == 'n')
  190. title[i] = ' ';
  191. for (i = 0; isspace(title[i]) ||
  192. title[i] == '"'; i++)
  193. ;
  194. for (j = 0; title[i]; j++)
  195. title[j] = title[i++];
  196. title[j] = '';
  197. for (j = strlen(title) - 1;
  198. (j && isspace(title[j]))
  199. || title[j] == '' || title[j] == '"'; j--)
  200. title[j] = '';
  201. for (j = 0; title[j]; j++)
  202. if (title[j] == '"')
  203. title[j] = ''';
  204. free(tag);
  205. return *title ? title : shorttitle;
  206. }
  207. else {
  208. if (lstrstr(tag, "<title>"))
  209. status = TI_FOUND;
  210. }
  211. break;
  212. default:
  213. if (status == TI_FOUND) {
  214. *p = c;
  215. p++;
  216. }
  217. else {
  218. if (status == TI_CLOSE) {
  219. fclose(fp);
  220. free(tag);
  221. return shorttitle;
  222. }
  223. }
  224. }
  225. }
  226. fclose(fp);
  227. free(tag);
  228. return shorttitle;
  229. }
  230. /* Malloc()'s a string, returns it.
  231. */
  232. char *mystrdup(s)
  233.      char *s;
  234. {
  235. char *p;
  236. p = (char *) emalloc(strlen(s) + 1);
  237. strcpy(p, s);
  238. return p;
  239. }
  240. /* Is a character a valid word character?
  241. */
  242. int iswordchar(char c)
  243. {
  244. int d, i;
  245. d = tolower(c);
  246. for (i = 0; wordchars[i] != ''; i++)
  247. {
  248. if ((char)d == wordchars[i])
  249. return 1;
  250. }
  251. return 0;
  252. }
  253. /* In a string, replaces all occurrences of "oldpiece" with "newpiece".
  254. ** This is not really bulletproof yet.
  255. */
  256. char *replace(string, oldpiece, newpiece)
  257.      char *string;
  258.      char *oldpiece;
  259.      char *newpiece;
  260. {
  261. int i, j, limit;
  262. char *c;
  263. char beforestring[MAXSTRLEN], afterstring[MAXSTRLEN];
  264. static char newstring[MAXSTRLEN];
  265. if ((c = (char *) strstr(string, oldpiece)) == NULL)
  266. return string;
  267. limit = c - string;
  268. for (i = 0; i < limit; i++)
  269. beforestring[i] = string[i];
  270. beforestring[i] = '';
  271. i += strlen(oldpiece);
  272. for (j = 0; string[i] != ''; i++)
  273. afterstring[j++] = string[i];
  274. afterstring[j] = '';
  275. sprintf(newstring, "%s%s%s", beforestring, newpiece, afterstring);
  276. while (strstr(newstring, oldpiece))
  277. strcpy(newstring, replace(newstring, oldpiece, newpiece));
  278. return newstring;
  279. }
  280. /* Just for A.P. and K.H. 2/5/98 by G.Hill - not really used now */
  281. char* replaceWild (char* fileName, char* pattern, char* subs)
  282. {
  283. int i;
  284. for (i = 0; pattern[i] != '*' && fileName[i] != ''; i++) 
  285.     {
  286. if (fileName[i] != pattern[i])
  287. return fileName;
  288.     }
  289. return subs;
  290. }
  291. /* Like strcmp(), but the order of sorting the first char is
  292. ** determined by the order of the characters in the wordchars array.
  293. */
  294. int wordcompare(s1, s2)
  295.      char *s1;
  296.      char *s2;
  297. {
  298. register int i, j;
  299. if (s1[0] != s2[0]) {
  300. for (i = 0; wordchars[i] != ''; i++)
  301. if (s1[0] == wordchars[i])
  302. break;
  303. for (j = 0; wordchars[j] != ''; j++)
  304. {
  305. if (s2[0] == wordchars[j])
  306. break;
  307. }
  308. if (i < j)
  309. return -1;
  310. else
  311. return 1;
  312. }
  313. else
  314. return strcmp(s1, s2);
  315. }
  316. /* This converts HTML numbered entities (such as &#169;)
  317. ** to strings (like &copy;). Much is this function is
  318. ** simply adding semicolons in the right places.
  319. ** This and the functions it calls are not very fast
  320. ** and could be made faster.
  321. */
  322. char *convertentities(s)
  323. char *s;
  324. {
  325. int i, skip;
  326. char ent[MAXENTLEN];
  327. static char newword[MAXWORDLEN];
  328. if ((char *) strchr(s, '&') == NULL)
  329. return s;
  330. if (strlen(s) > maxwordlimit)
  331. return s;
  332. for (i = 0; i < MAXWORDLEN; i++)
  333. newword[i] = '';
  334. for (; *s != ''; s++) {
  335. if (*s == '&') {
  336. strcpy(ent, getent(s, &skip));
  337. if (ent[0] == '') {
  338. sprintf(newword, "%s&", newword);
  339. continue;
  340. }
  341. s += skip;
  342. if (*s == ';')
  343. s++;
  344. sprintf(newword, "%s%s;", newword, ent);
  345. s--;
  346. }
  347. else
  348. sprintf(newword, "%s%c", newword, *s);
  349. }
  350. strcpy(newword, (char *) converttonamed(newword));
  351. if (ASCIIENTITIES)
  352. strcpy(newword, (char *) converttoascii(newword));
  353. return newword;
  354. }
  355. /* Returns a matching entity that matches the beginning of a string, if any.
  356. */
  357. char *getent(s, skip)
  358. char *s;
  359. int *skip;
  360. {
  361. int i;
  362. static char ent[MAXENTLEN], testent[MAXENTLEN];
  363. *skip = 0;
  364. strncpy(ent, s, MAXENTLEN);
  365. if (ent[1] == '#') {
  366. if (isdigit(ent[5]))
  367. return "";
  368. for (i = 2; ent[i] != '' && isdigit(ent[i]); i++)
  369. ;
  370. while (ent[i] != '' && !isdigit(ent[i]))
  371. ent[i++] = '';
  372. *skip = strlen(ent);
  373. return ent;
  374. }
  375. else {
  376. for (i = 0; entities[i] != NULL; i += 3) {
  377. strcpy(testent, entities[i]);
  378. if (testent[0] != '') {
  379. if (!strncmp(testent, ent, strlen(testent))) {
  380. strcpy(ent, testent);
  381. *skip = strlen(ent);
  382. return ent;
  383. }
  384. }
  385. }
  386. }
  387. return "";
  388. }
  389. /* This is the real function called by convertentities() that
  390. ** changes numbered to named entities.
  391. */
  392. char *converttonamed(s)
  393. char *s;
  394. {
  395. int i;
  396. char testent[MAXENTLEN], newent[MAXENTLEN];
  397. static char newword[MAXWORDLEN];
  398. strcpy(newword, s);
  399. for (i = 0; entities[i] != NULL; i += 3) {
  400. sprintf(testent, "%s;", entities[i + 1]);
  401. if (strstr(newword, testent) != NULL &&
  402. (entities[i])[0] != '') {
  403. sprintf(newent, "%s;", entities[i]);
  404. strcpy(newword, (char *) replace(newword,
  405. testent, newent));
  406. }
  407. }
  408. while (hasnumbered(newword))
  409. strcpy(newword, (char *) converttonamed(newword));
  410. return newword;
  411. }
  412. /* Does a string still contain numbered entities that can be converted?
  413. */
  414. int hasnumbered(s)
  415. char *s;
  416. {
  417. int i;
  418. char testent[MAXENTLEN];
  419. for (i = 0; entities[i] != NULL; i += 3) {
  420. sprintf(testent, "%s;", entities[i + 1]);
  421. if (strstr(s, testent) != NULL && (entities[i])[0] != '')
  422. return 1;
  423. }
  424. return 0;
  425. }
  426. /* This function converts all convertable named and numbered
  427. ** entities to their ASCII equivalents, if they exist.
  428. */
  429. char *converttoascii(s)
  430. char *s;
  431. {
  432. int i;
  433. char *c, *d, wrdent[MAXENTLEN], nument[MAXENTLEN];
  434. static char newword[MAXWORDLEN];
  435. strcpy(newword, s);
  436. for (i = 0; entities[i] != NULL; i += 3) {
  437. sprintf(wrdent, "%s;", entities[i]);
  438. sprintf(nument, "%s;", entities[i + 1]);
  439. c = d = NULL;
  440. if ((entities[i])[0] != '')
  441. c = (char *) strstr(newword, wrdent);
  442. if ((entities[i + 1])[0] != '')
  443. d = (char *) strstr(newword, nument);
  444. if ((entities[i + 2])[0] != '') {
  445. if (c != NULL)
  446. strcpy(newword, (char *) replace(newword,
  447. wrdent, entities[i + 2]));
  448. if (d != NULL)
  449. strcpy(newword, (char *) replace(newword,
  450. nument, entities[i + 2]));
  451. }
  452. }
  453. while (hasnonascii(newword))
  454. strcpy(newword, (char *) converttoascii(newword));
  455. return newword;
  456. }
  457. /* Does a string still contain numbered or named entities that can
  458. ** be converted to ascii equivalents?
  459. */
  460. int hasnonascii(s)
  461. char *s;
  462. {
  463. int i;
  464. char *c, *d, wrdent[MAXENTLEN], nument[MAXENTLEN];
  465. for (i = 0; entities[i] != NULL; i += 3) {
  466. sprintf(wrdent, "%s;", entities[i]);
  467. sprintf(nument, "%s;", entities[i + 1]);
  468. c = d = NULL;
  469. if ((entities[i])[0] != '')
  470. c = (char *) strstr(s, wrdent);
  471. if ((entities[i + 1])[0] != '')
  472. d = (char *) strstr(s, nument);
  473. if ((entities[i + 2])[0] != '')
  474. if (c != NULL || d != NULL)
  475. return 1;
  476. }
  477. return 0;
  478. }
  479. /* That regular expression matching and replacing thing */
  480. char * matchAndChange (char *str, char *pattern, char *subs) 
  481. {
  482. int  status, lenSub, lenBeg, lenTmp;
  483. regex_t re;
  484. regmatch_t pmatch[MAXPAR];
  485. char *tmpstr;
  486. char begin[MAXSTRLEN],newstr[MAXSTRLEN];
  487. static char oldStr[MAXSTRLEN];
  488. /* Save the old string just in case */
  489. strcpy(oldStr,str);
  490. status = regcomp(&re, pattern, REG_EXTENDED);
  491. if ( status != 0) {
  492. return oldStr;
  493. }
  494. status = regexec(&re,str,(size_t)MAXPAR,pmatch,0);
  495. if (status != 0)
  496. return oldStr;
  497. tmpstr = str;
  498. while (!status) {
  499. /* Stuff the new piece were needed */
  500. strncpy(begin,tmpstr,pmatch[0].rm_so); /* get the beginning */
  501. begin[pmatch[0].rm_so] = '';  /* Null terminate */
  502. lenTmp = strlen(tmpstr);
  503. lenSub = strlen(subs);
  504. lenBeg = strlen(begin);
  505. if ( (lenTmp + lenSub + lenBeg) >= MAXSTRLEN)
  506. return oldStr;
  507. sprintf (newstr, "%s%s%s", begin,subs,&(tmpstr[pmatch[0].rm_eo]));
  508. /* Copy the newstr into the tmpstr */
  509. strcpy(tmpstr,newstr);
  510. /* Position the pointer to the end of the subs string */
  511. tmpstr = &(tmpstr[pmatch[0].rm_so+lenSub]);
  512. status = regexec(&re,tmpstr,(size_t)5,pmatch,0);
  513. }
  514. regfree(&re);
  515. return str;
  516. }
  517. /*---------------------------------------------------------*/
  518. /* Match a regex and a string */
  519. int matchARegex( char *str, char *pattern) 
  520. {
  521. int  status;
  522. regex_t re;
  523. status = regcomp(&re, pattern, REG_EXTENDED);
  524. if ( status != 0)
  525. return 0;
  526. status = regexec(&re,str,(size_t)0,NULL,0);
  527. if (status != 0)
  528. return 0;
  529. return 1;
  530. }
  531. /*-----------------------------------------------------*/
  532. void makeItLow (char *str)
  533. {
  534.   int i;
  535.   int len = strlen(str);
  536.   for (i = 0; i < len; i++)
  537.     str[i] = tolower(str[i]);
  538. }
  539. /*----------------------------------------------------*/
  540. /* Check if a file with a particular suffix should be indexed
  541. ** according to the settings in the configuration file.
  542. */
  543. int isoksuffix(filename, rulelist)
  544. char *filename;
  545. struct swline *rulelist;
  546. {
  547. int badfile;
  548. char *c, suffix[MAXSUFFIXLEN], checksuffix[MAXSUFFIXLEN];
  549. struct swline *tmplist;
  550. tmplist = rulelist;
  551. if (tmplist == NULL)
  552. return 1;
  553. if ((c = (char *) strrchr(filename, '.')) == NULL)
  554. return 0;
  555. if (strlen(c+1) >= MAXSUFFIXLEN)
  556.   return 0;
  557. badfile = 1;
  558. strcpy(checksuffix, c + 1);
  559. while (tmplist != NULL) {
  560. if ((c = (char *) strrchr(tmplist->line, '.')) == NULL)
  561. strcpy(suffix, tmplist->line);
  562. else
  563. strcpy(suffix, c + 1);
  564. if (lstrstr(suffix, checksuffix) && strlen(suffix) ==
  565. strlen(checksuffix))
  566. badfile = 0;
  567. tmplist = tmplist->next;
  568. }
  569. return !(badfile);
  570. }