/* * Copyright (c) 1997, 1998, 1999, 2000, 2004 * Tama Communications Corporation * * This file is part of GNU GLOBAL. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifdef HAVE_CONFIG_H #include #endif #include #ifdef HAVE_STRING_H #include #else #include #endif #ifdef DEBUG #include extern int debug; #endif #include "locatestring.h" /* String locator: usage and memory status 'v': result pointer string = "ABC XYZ XYZ ABC" pointer = locatestring(string, "XYZ", MATCH_FIRST); v "ABC XYZ XYZ ABC" pointer = locatestring(string, "XYZ", MATCH_LAST); v "ABC XYZ XYZ ABC" pointer = locatestring(string, "XYZ", MATCH_AT_FIRST); "ABC XYZ XYZ ABC" (nothing pointed) pointer = locatestring(string, "ABC", MATCH_AT_FIRST); v "ABC XYZ XYZ ABC" (point the following character) pointer = locatestring(string, "ABC", MATCH_AT_LAST); v "ABC XYZ XYZ ABC" pointer = locatestring(string, "ABC XYZ XYZ ABC", MATCH_COMPLETE); v "ABC XYZ XYZ ABC" pointer = locatestring(string, "xyZ", MATCH_FIRST|IGNORE_CASE); v "ABC XYZ XYZ ABC" */ /* * strincmp: strncmp with ignoring case. * * Interface is same with strncmp. */ static int strincmp(const char *string, const char *pattern, size_t len) { unsigned char s, p; while (len--) { s = tolower((unsigned char)*string++); p = tolower((unsigned char)*pattern++); if (s != p) return s - p; if (s == 0) break; } return 0; } /* * locatestring: locate pattern from string * * i) string string * i) pattern pattern * i) flag MATCH_FIRST: match first * MATCH_AT_FIRST: match only at first column * MATCH_LAST: match last * MATCH_AT_LAST: match only at last column * MATCH_COMPLETE match completely * IGNORE_CASE: Ignore case * r) pointer or NULL * If the flag == MATCH_AT_FIRST then the pointer * points the following character of the matched * string, else points at the head of it. * * This function is made to avoid compatibility problems. */ char * locatestring(const char *string, const char *pattern, int flag) { int c = *pattern; int plen = strlen(pattern); const char *p = NULL; int slen; int (*cmpfunc) (const char *, const char*, size_t); #ifdef DEBUG FILE *dbg = stderr; const char *pre = string; #endif cmpfunc = (flag & IGNORE_CASE) ? strincmp : strncmp; flag &= ~IGNORE_CASE; if (flag == MATCH_COMPLETE) { if (strlen(string) == plen && !(*cmpfunc)(string, pattern, plen)) return (char *)string; else return NULL; } if (flag == MATCH_AT_LAST && (slen = strlen(string)) > plen) string += (slen - plen); for (; *string; string++) { if (*string == c) if (!(*cmpfunc)(string, pattern, plen)) { p = string; if (flag == MATCH_FIRST) break; } if (flag == MATCH_AT_FIRST || flag == MATCH_AT_LAST) break; } #ifdef DEBUG if (debug) { fprintf(dbg, "locatestring: "); if (p == NULL) fprintf(dbg, "%s", pre); else { const char *pp = p; const char *post = pp + strlen(pattern); for (; *pre && pre < pp; pre++) fputc(*pre, dbg); fputc('[', dbg); for (; *pp && pp < post; pp++) fputc(*pp, dbg); fputc(']', dbg); for (; *post; post++) fputc(*post, dbg); } fputc('\n', dbg); } #endif if (p && flag == MATCH_AT_FIRST) p += plen; return (char *)p; }