void literal_search(CONVERT *cv, const char *file) { struct words *c; int ccount; char *p; char *buf; struct stat stb; char *linep; long lineno; int f; if ((f = open(file, 0)) < 0) die("cannot open '%s'.", file); if (fstat(f, &stb) < 0) die("cannot fstat '%s'.", file); if (stb.st_size == 0) goto skip_empty_file; #ifdef HAVE_MMAP buf = mmap(0, stb.st_size, PROT_READ, MAP_SHARED, f, 0); if (buf == MAP_FAILED) die("mmap failed (%s).", file); #else #ifdef HAVE_ALLOCA buf = (char *)alloca(stb.st_size); #else buf = (char *)malloc(stb.st_size); #endif if (buf == NULL) die("short of memory."); if (read(f, buf, stb.st_size) < stb.st_size) die("read failed (%s).", file); #endif linep = p = buf; ccount = stb.st_size; lineno = 1; c = w; for (;;) { if (--ccount <= 0) break; nstate: if (ccomp(c->inp, *p)) { c = c->nst; } else if (c->link != 0) { c = c->link; goto nstate; } else { c = c->fail; if (c==0) { c = w; istate: if (ccomp(c->inp , *p)) { c = c->nst; } else if (c->link != 0) { c = c->link; goto istate; } } else goto nstate; } if (c->out) { while (*p++ != '\n') { if (--ccount <= 0) break; } if (Vflag) goto nomatch; succeed: if (cv->format == FORMAT_PATH) { convert_put_path(cv, file); goto finish; } else { STATIC_STRBUF(sb); strbuf_clear(sb); strbuf_nputs(sb, linep, p - linep); strbuf_unputc(sb, '\n'); strbuf_unputc(sb, '\r'); convert_put_using(cv, encoded_pattern, file, lineno, strbuf_value(sb), NULL); } nomatch: lineno++; linep = p; c = w; continue; } if (*p++ == '\n') { if (Vflag) goto succeed; else { lineno++; linep = p; c = w; } } } finish: #ifdef HAVE_MMAP munmap(buf, stb.st_size); #elif HAVE_ALLOCA #else free(buf); #endif skip_empty_file: close(f); }
/** * literal_search: execute literal search * * @param[in] cv CONVERT structure * @param[in] file file to search * @return 0: normal, -1: error */ int literal_search(CONVERT *cv, const char *file) { # define ccomp(a,b) (iflag ? lca(a)==lca(b) : a==b) # define lca(x) (isupper(x) ? tolower(x) : x) struct words *c; int ccount; char *p; char *buf; struct stat stb; char *linep; long lineno; int f; int count = 0; if ((f = open(file, O_BINARY)) < 0) { warning("cannot open '%s'.", file); return -1; } if (fstat(f, &stb) < 0) { warning("cannot fstat '%s'.", file); goto skip_empty_file; } if (stb.st_size == 0) goto skip_empty_file; #ifdef HAVE_MMAP buf = mmap(0, stb.st_size, PROT_READ, MAP_SHARED, f, 0); if (buf == MAP_FAILED) die("mmap failed (%s).", file); #elif _WIN32 { HANDLE hMap = CreateFileMapping((HANDLE)_get_osfhandle(f), NULL, PAGE_READONLY, 0, stb.st_size, NULL); if (hMap == NULL) die("CreateFileMapping failed (%s).", file); buf = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0); if (buf == NULL) die("MapViewOfFile failed (%s).", file); #else #ifdef HAVE_ALLOCA buf = (char *)alloca(stb.st_size); #else buf = (char *)malloc(stb.st_size); #endif if (buf == NULL) die("short of memory."); if (read(f, buf, stb.st_size) < stb.st_size) die("read failed (%s).", file); #endif linep = p = buf; ccount = stb.st_size; lineno = 1; c = w; for (;;) { if (--ccount < 0) break; nstate: if (ccomp(c->inp, *p)) { c = c->nst; } else if (c->link != 0) { c = c->link; goto nstate; } else { c = c->fail; if (c==0) { c = w; istate: if (ccomp(c->inp , *p)) { c = c->nst; } else if (c->link != 0) { c = c->link; goto istate; } } else goto nstate; } if (c->out) { while (*p++ != '\n') { if (--ccount < 0) break; } if (Vflag) goto nomatch; succeed: if (cv->format == FORMAT_PATH) { convert_put_path(cv, NULL, file); count++; goto finish; } else { STATIC_STRBUF(sb); strbuf_clear(sb); strbuf_nputs(sb, linep, p - linep); strbuf_unputc(sb, '\n'); strbuf_unputc(sb, '\r'); convert_put_using(cv, pattern, file, lineno, strbuf_value(sb), NULL); count++; } nomatch: lineno++; linep = p; c = w; continue; } if (*p++ == '\n' || ccount == 0) { if (Vflag) goto succeed; else { lineno++; linep = p; c = w; } } } finish: #ifdef HAVE_MMAP munmap(buf, stb.st_size); #elif _WIN32 UnmapViewOfFile(buf); CloseHandle(hMap); } #elif HAVE_ALLOCA #else free(buf); #endif skip_empty_file: close(f); return count; }