root/global/literal.c

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

DEFINITIONS

This source file includes following definitions.
  1. literal_comple
  2. literal_search
  3. cgotofn
  4. cfail
  5. overflo

   1 /*
   2  * Copyright(C) Caldera International Inc.  2001-2002.  All rights reserved.
   3  *
   4  * See 'Caldera Ancient Unix License' in 'LICENSE' file.
   5  *
   6  * Copyright (c) 2012 Tama Communications Corporation
   7  *
   8  * This file is part of GNU GLOBAL.
   9  *
  10  * This program is free software: you can redistribute it and/or modify
  11  * it under the terms of the GNU General Public License as published by
  12  * the Free Software Foundation, either version 3 of the License, or
  13  * (at your option) any later version.
  14  * 
  15  * This program is distributed in the hope that it will be useful,
  16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18  * GNU General Public License for more details.
  19  * 
  20  * You should have received a copy of the GNU General Public License
  21  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  22  */
  23 /*
  24  * This code was derived from /usr/src/usr.bin/fgrep.c in 4.3 Berkeley
  25  * Software Distribution (4.3BSD) by the University of California.
  26  * Since GNU grep is very strong, I would like to include its code into
  27  * global command in near future.
  28  */
  29 #ifdef HAVE_CONFIG_H
  30 #include <config.h>
  31 #endif
  32 #include <stdio.h>
  33 #include <ctype.h>
  34 #include <sys/param.h>
  35 #include <sys/stat.h>
  36 #include <errno.h>
  37 #ifdef STDC_HEADERS
  38 #include <stdlib.h>
  39 #endif
  40 #ifdef HAVE_MMAP
  41 #include <sys/mman.h>
  42 #elif _WIN32
  43 #define WIN32_LEAN_AND_MEAN
  44 #include <windows.h>
  45 #endif
  46 #ifdef HAVE_FCNTL_H
  47 #include <fcntl.h>
  48 #endif
  49 #ifdef HAVE_UNISTD_H
  50 #include <unistd.h>
  51 #endif
  52 #include "format.h"
  53 #include "pathconvert.h"
  54 #include "die.h"
  55 
  56 #ifndef O_BINARY
  57 #define O_BINARY 0
  58 #endif
  59 
  60 void overflo(void);
  61 void cgotofn(const char *);
  62 void cfail(void);
  63 
  64 extern int iflag;
  65 extern int Vflag;
  66 extern void encode(char *, int, const char *);
  67 
  68 #define MAXSIZ 6000
  69 #define QSIZE 400
  70 static struct words {
  71         char    inp;
  72         char    out;
  73         struct  words *nst;
  74         struct  words *link;
  75         struct  words *fail;
  76 } w[MAXSIZ], *smax, *q;
  77 
  78 static char encoded_pattern[IDENTLEN];
  79 
  80 /**
  81  * literal_comple: compile literal for search.
  82  *
  83  *      @param[in]      pattern literal string
  84  *
  85  * Literal string is treated as is.
  86  */
  87 void
  88 literal_comple(const char *pattern)
  89 {
  90         /*
  91          * convert spaces into %FF format.
  92          */
  93         encode(encoded_pattern, sizeof(encoded_pattern), pattern);
  94         /*
  95          * construct a goto table.
  96          */
  97         cgotofn(pattern);
  98         /*
  99          * construct fail links.
 100          */
 101         cfail();
 102 }
 103 /**
 104  * literal_search: execute literal search
 105  *
 106  *      @param[in]      file    file to search
 107  *      @return         0: normal, -1: error
 108  */
 109 # define ccomp(a,b) (iflag ? lca(a)==lca(b) : a==b)
 110 # define lca(x) (isupper(x) ? tolower(x) : x)
 111 void
 112 literal_search(CONVERT *cv, const char *file)
 113 {
 114         struct words *c;
 115         int ccount;
 116         char *p;
 117         char *buf;
 118         struct stat stb;
 119         char *linep;
 120         long lineno;
 121         int f;
 122 
 123         if ((f = open(file, O_BINARY)) < 0) {
 124                 warning("cannot open '%s'.", file);
 125                 return;
 126         }
 127         if (fstat(f, &stb) < 0) {
 128                 warning("cannot fstat '%s'.", file);
 129                 goto skip_empty_file;
 130         }
 131         if (stb.st_size == 0)
 132                 goto skip_empty_file;
 133 #ifdef HAVE_MMAP
 134         buf = mmap(0, stb.st_size, PROT_READ, MAP_SHARED, f, 0);
 135         if (buf == MAP_FAILED)
 136                 die("mmap failed (%s).", file);
 137 #elif _WIN32
 138         {
 139         HANDLE hMap = CreateFileMapping((HANDLE)_get_osfhandle(f), NULL, PAGE_READONLY, 0, stb.st_size, NULL);
 140         if (hMap == NULL)
 141                 die("CreateFileMapping failed (%s).", file);
 142         buf = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);
 143         if (buf == NULL)
 144                 die("MapViewOfFile failed (%s).", file);
 145 #else
 146 #ifdef HAVE_ALLOCA
 147         buf = (char *)alloca(stb.st_size);
 148 #else
 149         buf = (char *)malloc(stb.st_size);
 150 #endif
 151         if (buf == NULL)
 152                 die("short of memory.");
 153         if (read(f, buf, stb.st_size) < stb.st_size)
 154                 die("read failed (%s).", file);
 155 #endif
 156         linep = p = buf;
 157         ccount = stb.st_size;
 158         lineno = 1;
 159         c = w;
 160         for (;;) {
 161                 if (--ccount <= 0)
 162                         break;
 163                 nstate:
 164                         if (ccomp(c->inp, *p)) {
 165                                 c = c->nst;
 166                         }
 167                         else if (c->link != 0) {
 168                                 c = c->link;
 169                                 goto nstate;
 170                         }
 171                         else {
 172                                 c = c->fail;
 173                                 if (c==0) {
 174                                         c = w;
 175                                         istate:
 176                                         if (ccomp(c->inp , *p)) {
 177                                                 c = c->nst;
 178                                         }
 179                                         else if (c->link != 0) {
 180                                                 c = c->link;
 181                                                 goto istate;
 182                                         }
 183                                 }
 184                                 else goto nstate;
 185                         }
 186                 if (c->out) {
 187                         while (*p++ != '\n') {
 188                                 if (--ccount <= 0)
 189                                         break;
 190                         }
 191                         if (Vflag)
 192                                 goto nomatch;
 193         succeed:        if (cv->format == FORMAT_PATH) {
 194                                 convert_put_path(cv, file);
 195                                 goto finish;
 196                         } else {
 197                                 STATIC_STRBUF(sb);
 198 
 199                                 strbuf_clear(sb);
 200                                 strbuf_nputs(sb, linep, p - linep);
 201                                 strbuf_unputc(sb, '\n');
 202                                 strbuf_unputc(sb, '\r');
 203                                 convert_put_using(cv, encoded_pattern, file, lineno, strbuf_value(sb), NULL);
 204                         }
 205         nomatch:        lineno++;
 206                         linep = p;
 207                         c = w;
 208                         continue;
 209                 }
 210                 if (*p++ == '\n') {
 211                         if (Vflag)
 212                                 goto succeed;
 213                         else {
 214                                 lineno++;
 215                                 linep = p;
 216                                 c = w;
 217                         }
 218                 }
 219         }
 220 finish:
 221 #ifdef HAVE_MMAP
 222         munmap(buf, stb.st_size);
 223 #elif _WIN32
 224         UnmapViewOfFile(buf);
 225         CloseHandle(hMap);
 226         }
 227 #elif HAVE_ALLOCA
 228 #else
 229         free(buf);
 230 #endif
 231 skip_empty_file:
 232         close(f);
 233 }
 234 /**
 235  * make automaton.
 236  */
 237 void
 238 cgotofn(const char *pattern) {
 239         int c;
 240         struct words *s;
 241 
 242         s = smax = w;
 243 nword:  for(;;) {
 244                 c = *pattern++;
 245                 if (c==0)
 246                         return;
 247                 if (c == '\n') {
 248                         s->out = 1;
 249                         s = w;
 250                 } else {
 251                 loop:   if (s->inp == c) {
 252                                 s = s->nst;
 253                                 continue;
 254                         }
 255                         if (s->inp == 0) goto enter;
 256                         if (s->link == 0) {
 257                                 if (smax >= &w[MAXSIZ - 1])
 258                                         overflo();
 259                                 s->link = ++smax;
 260                                 s = smax;
 261                                 goto enter;
 262                         }
 263                         s = s->link;
 264                         goto loop;
 265                 }
 266         }
 267         enter:
 268         do {
 269                 s->inp = c;
 270                 if (smax >= &w[MAXSIZ - 1])
 271                         overflo();
 272                 s->nst = ++smax;
 273                 s = smax;
 274         } while ((c = *pattern++) != '\n' && c!=0);
 275         smax->out = 1;
 276         s = w;
 277         if (c != 0)
 278                 goto nword;
 279 }
 280 
 281 void
 282 cfail() {
 283         struct words *queue[QSIZE];
 284         struct words **front, **rear;
 285         struct words *state;
 286         int bstart;
 287         char c;
 288         struct words *s;
 289 
 290         s = w;
 291         front = rear = queue;
 292 init:   if ((s->inp) != 0) {
 293                 *rear++ = s->nst;
 294                 if (rear >= &queue[QSIZE - 1])
 295                         overflo();
 296         }
 297         if ((s = s->link) != 0) {
 298                 goto init;
 299         }
 300 
 301         while (rear != front) {
 302                 s = *front;
 303                 if (front == &queue[QSIZE-1])
 304                         front = queue;
 305                 else front++;
 306         cloop:  if ((c = s->inp) != 0) {
 307                         bstart = 0;
 308                         *rear = (q = s->nst);
 309                         if (front < rear)
 310                                 if (rear >= &queue[QSIZE-1])
 311                                         if (front == queue) overflo();
 312                                         else rear = queue;
 313                                 else rear++;
 314                         else
 315                                 if (++rear == front) overflo();
 316                         state = s->fail;
 317                 floop:  if (state == 0) {
 318                                 state = w;
 319                                 bstart = 1;
 320                         }
 321                         if (state->inp == c) {
 322                         qloop:  q->fail = state->nst;
 323                                 if ((state->nst)->out == 1)
 324                                         q->out = 1;
 325                                 if ((q = q->link) != 0)
 326                                         goto qloop;
 327                         }
 328                         else if ((state = state->link) != 0)
 329                                 goto floop;
 330                         else if (bstart == 0){
 331                                 state = 0;
 332                                 goto floop;
 333                         }
 334                 }
 335                 if ((s = s->link) != 0)
 336                         goto cloop;
 337         }
 338 }
 339 void
 340 overflo() {
 341         die("wordlist too large.");
 342 }

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