## root/libutil/locatestring.c(108.html)

/* [<][>][^][v][top][bottom][index][help] */

## DEFINITIONS

This source file includes following definitions.

1. strincmp
2. locatestring

    /*
     * 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 <http://www.gnu.org/licenses/>.
     */

    #ifdef HAVE_CONFIG_H
    #include <config.h>
    #endif
    #include <ctype.h>
    #ifdef HAVE_STRING_H
    #include <string.h>
    #else
    #include <strings.h>
    #endif
    #ifdef DEBUG
    #include <stdio.h>
    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;
    }

/* [<][>][^][v][top][bottom][index][help] */