root/libutil/locatestring.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. strincmp
  2. locatestring

   1 /*
   2  * Copyright (c) 1997, 1998, 1999, 2000, 2004, 2011
   3  *      Tama Communications Corporation
   4  *
   5  * This file is part of GNU GLOBAL.
   6  *
   7  * This program is free software: you can redistribute it and/or modify
   8  * it under the terms of the GNU General Public License as published by
   9  * the Free Software Foundation, either version 3 of the License, or
  10  * (at your option) any later version.
  11  * 
  12  * This program is distributed in the hope that it will be useful,
  13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15  * GNU General Public License for more details.
  16  * 
  17  * You should have received a copy of the GNU General Public License
  18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  19  */
  20 
  21 #ifdef HAVE_CONFIG_H
  22 #include <config.h>
  23 #endif
  24 #include <ctype.h>
  25 #ifdef HAVE_STRING_H
  26 #include <string.h>
  27 #else
  28 #include <strings.h>
  29 #endif
  30 
  31 #include "die.h"
  32 #include "locatestring.h"
  33 
  34 /** @file
  35 
  36 String locator: usage and memory status
  37 
  38         'v': result pointer
  39  
  40 @code
  41 string = "ABC XYZ XYZ ABC"
  42 
  43 pointer = locatestring(string, "XYZ", MATCH_FIRST);
  44              v
  45         "ABC XYZ XYZ ABC"
  46 
  47 pointer = locatestring(string, "XYZ", MATCH_LAST);
  48                  v
  49         "ABC XYZ XYZ ABC"
  50 
  51 pointer = locatestring(string, "XYZ", MATCH_AT_FIRST);
  52 
  53         "ABC XYZ XYZ ABC" (nothing pointed)
  54 
  55 pointer = locatestring(string, "ABC", MATCH_AT_FIRST);
  56             v
  57         "ABC XYZ XYZ ABC" (point the following character)
  58 
  59 pointer = locatestring(string, "ABC", MATCH_AT_LAST);
  60                      v
  61         "ABC XYZ XYZ ABC"
  62 
  63 pointer = locatestring(string, "ABC XYZ XYZ ABC", MATCH_COMPLETE);
  64          v
  65         "ABC XYZ XYZ ABC"
  66 
  67 pointer = locatestring(string, "xyZ", MATCH_FIRST|IGNORE_CASE);
  68              v
  69         "ABC XYZ XYZ ABC"
  70 @endcode
  71  */
  72 
  73 /**
  74  * strincmp: strncmp with ignoring case.
  75  *
  76  *      Interface is same with @NAME{strncmp}.
  77  */
  78 static int
  79 strincmp(const char *string, const char *pattern, size_t len)
  80 {
  81         unsigned char s, p;
  82 
  83         while (len--) {
  84                 /*
  85                  * In some systems, tolower() are #define macros,
  86                  * where the argument gets evaluated more than once.
  87                  */
  88                 s = tolower((unsigned char)*string);
  89                 p = tolower((unsigned char)*pattern);
  90                 if (s != p)
  91                         return s - p;
  92                 if (s == 0)
  93                         break;
  94                 string++;
  95                 pattern++;
  96         }
  97         return 0;
  98 }
  99 
 100 /**
 101  * locatestring: locate pattern from string
 102  *
 103  *      @param[in]      string  string
 104  *      @param[in]      pattern pattern
 105  *      @param[in]      flag    MATCH_FIRST:    match first <br>
 106  *                      MATCH_AT_FIRST: match only at first column <br>
 107  *                      MATCH_LAST:     match last <br>
 108  *                      MATCH_AT_LAST:  match only at last column <br>
 109  *                      MATCH_COMPLETE  match completely <br>
 110  *                      IGNORE_CASE:    Ignore case
 111  *      @return         pointer or NULL
 112  *                      If the flag == MATCH_AT_FIRST then the pointer <br>
 113  *                      points the following character of the matched <br>
 114  *                      string, else points at the head of it.
 115  *
 116  * This function is made to avoid compatibility problems.
 117  */
 118 char *
 119 locatestring(const char *string, const char *pattern, int flag)
 120 {
 121         int plen = strlen(pattern);
 122         const char *p = NULL;
 123         int (*cmpfunc) (const char *, const char*, size_t);
 124 
 125         cmpfunc = (flag & IGNORE_CASE) ? strincmp : strncmp;
 126         flag &= ~IGNORE_CASE;
 127 
 128         if (flag == MATCH_COMPLETE) {
 129                 if (strlen(string) == plen && !(*cmpfunc)(string, pattern, plen))
 130                         p = string;
 131         } else if (flag == MATCH_AT_FIRST) {
 132                 if (!(*cmpfunc)(string, pattern, plen))
 133                         p = string + plen;
 134         } else if (flag == MATCH_AT_LAST) {
 135                 int slen = strlen(string);
 136 
 137                 if (slen >= plen) {
 138                         string += (slen - plen);
 139                         if (!(*cmpfunc)(string, pattern, plen))
 140                                 p = string;
 141                 }
 142         } else if (flag == MATCH_FIRST || flag == MATCH_LAST) {
 143                 int slen = strlen(string);
 144 
 145                 for (; *string; string++, slen--) {
 146                         if (slen < plen)
 147                                 break;
 148                         if (!(*cmpfunc)(string, pattern, plen)) {
 149                                 p = string;
 150                                 if (flag == MATCH_FIRST)
 151                                         break;
 152                         }
 153                 }
 154         } else {
 155                 die("usage error of locatestring() (flag = %d).", flag);
 156         }
 157         return (char *)p;
 158 }

/* [previous][next][first][last][top][bottom][index][help] */