This repository has been archived on 2024-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
deb-goldedplus/goldlib/gall/gbmh.cpp

141 lines
3.6 KiB
C++

// This may look like C code, but it is really -*- C++ -*-
// ------------------------------------------------------------------
// The Goldware Library
// Copyright (C) 1990-1999 Odinn Sorensen
// Copyright (C) 2000 Alexander S. Aganichev
// ------------------------------------------------------------------
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this program; if not, write to the Free
// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
// MA 02111-1307, USA
// ------------------------------------------------------------------
// $Id$
// ------------------------------------------------------------------
// Boyer-Moore-Horspool pattern match.
// ------------------------------------------------------------------
// Based on Public Domain version by Thad Smith 7/21/1992, based on a
// 7/92 public domain BMH version by Raymond Gardner.
// With fixes found by Jeff Dunlop 10/21/93.
// ------------------------------------------------------------------
#include <climits>
#include <gstrall.h>
#include <gmemdbg.h>
#include <gbmh.h>
// ------------------------------------------------------------------
gbmh::gbmh() {
pat = NULL;
}
// ------------------------------------------------------------------
gbmh::~gbmh() {
throw_deletearray(pat);
}
// ------------------------------------------------------------------
void gbmh::init(const char* pattern, bool ignorecase) {
ignore_case = ignorecase;
patlen = strlen(pattern);
pat = new char [patlen+1];
throw_new(pat);
// Copy pattern
strcpy(pat, pattern);
if(ignore_case) {
#ifndef _MSC_VER
strupr(pat);
#else /* strupr() is wrong on windows 9x (patch from Ianos Gnatiuc 2:469/335.155) */
for(char *ptr = pat; *ptr; ptr++)
*ptr = g_toupper(*ptr);
#endif
}
// initialize skip array
int i;
for(i=0; i<256; i++)
skip[i] = patlen;
for(i=0; i<patlen; i++) {
skip[pat[i] & 0xff] = patlen - i - 1;
if(ignore_case)
skip[g_tolower((uint8_t)pat[i])] = patlen - i - 1;
}
char lastpatchar = pat[patlen - 1];
skip[lastpatchar & 0xff] = INT_MAX;
if(ignore_case)
skip[g_tolower((uint8_t)lastpatchar)] = INT_MAX;
// Horspool's fixed second shift
skip2 = patlen;
for(i=0; i<patlen-1; ++i)
if(pat[i] == lastpatchar)
skip2 = patlen - i - 1;
}
// ------------------------------------------------------------------
bool gbmh::find(const char* buffer) {
int buflen = strlen(buffer);
int i = patlen - 1 - buflen;
if(i >= 0)
return false;
buffer += buflen;
while(1) {
while((i += skip[buffer[i] & 0xff]) < 0)
;
if(i < (INT_MAX - buflen))
return false;
i -= INT_MAX;
int j = patlen - 1;
const char* s = buffer + (i - j);
if(ignore_case) {
while(--j >= 0 and g_toupper((uint8_t)s[j]) == pat[j])
;
}
else {
while(--j >= 0 and s[j] == pat[j])
;
}
if(j < 0)
return true;
if((i += skip2) >= 0)
return false;
}
}
// ------------------------------------------------------------------