/* $Header: /home/agc/src/libutf-2.8/RCS/gurep.c,v 1.7 1997/02/24 12:22:58 agc Exp agc $ */ /* * Copyright © 1996-1997 Alistair G. Crooks. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Alistair G. Crooks. * 4. The name of the author may not be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_SYS_STAT_H #include #endif #include #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_STRING_H #include #endif #include "utf.h" #include "ure.h" /* print the line number of `s', starting from `buf' */ int LineNum(char *buf, char *s) { Rune r; int i; int n; for (n = 1 ; buf <= s ; buf += i) { i = chartorune(&r, buf); if (r == '\n') { n++; } } return n; } /* print the line */ void PrintLine(char *up, ure_t *sp, char *from, char *to) { Rune r; char *cp; int i; for (cp = from; cp > up ; cp -= i) { i = priorrune(&r, cp); if (r == '\n') { break; } } for (;;) { i = chartorune(&r, cp); if (UNICODE_isascii(r)) { putchar((char)(r)); } else { printf("\\u%04x", r); } if (cp >= to && (r == '\n' || r == 0)) { break; } cp += i; } } /* get the file into memory */ static char * fgetfile(FILE *fp, int *size) { struct stat s; char *cp; int cc; (void) fstat(fileno(fp), &s); *size = s.st_size; cp = (char *) malloc(*size + 1); if (cp == (char *) NULL) { (void) fprintf(stderr, "Memory problems.\n"); exit(1); } cc = fread(cp, sizeof(char), *size, fp); if (cc != *size) { free(cp); return (char *) NULL; } cp[cc] = 0; return cp; } /* do a utf regexp search for each file */ int dofile(ure_t *sp, char *f, int eflags, int pname, int plineno, int pline, char *collseq) { urematch_t matchv[10]; char *buf; char *cp; Rune r; char ebuf[BUFSIZ]; char done; FILE *fp; int ucc; int err; int i; if ((fp = fopen(f, "r")) == (FILE *) NULL) { return 0; } if ((buf = fgetfile(fp, &ucc)) == (char *) NULL) { return 0; } cp = buf; for (done = 0 ; !done ; ) { err = ureexec(sp, cp, 10, matchv, eflags, collseq); switch(err) { case URE_SUCCESS: if (pname) { printf("%s:", f); } if (plineno) { printf("%d:", LineNum(buf, &cp[matchv[0].rm_so])); } if (!pline) { (void) fclose(fp); return 1; } PrintLine(cp, sp, &cp[matchv[0].rm_so], &cp[matchv[0].rm_eo]); cp = utfrune(&cp[matchv[0].rm_eo], '\n'); if (cp == (char *) NULL) { done = 1; } i = chartorune(&r, cp); cp += i; if (r == 0) { done = 1; } break; case URE_NOMATCH: done = 1; break; default: ureerror(err, sp, ebuf, sizeof(ebuf)); (void) fprintf(stderr, "Bad execution: %s\n", ebuf); done = 1; } } (void) fclose(fp); free(buf); return 1; } extern int optind; extern char *optarg; int main(int argc, char **argv) { ure_t u; char *collseq; char errmsg[BUFSIZ]; int plineno; int pline; int eflags; int err; int i; /* set defaults */ eflags = 0; plineno = 0; pline = 1; collseq = (char *) NULL; while ((i = getopt(argc, argv, "a:iln")) != -1) { switch(i) { case 'a': collseq = optarg; break; case 'i': eflags |= URE_ICASE; break; case 'l': pline = 0; break; case 'n': plineno = 1; break; } } if ((err = urecomp(&u, argv[optind], 0)) != URE_SUCCESS) { (void) ureerror(err, &u, errmsg, sizeof(errmsg)); (void) fprintf(stderr, "can't compile ure `%s', %s\n", (argv[optind] == (char *) NULL) ? "(null pattern)" : argv[optind], errmsg); exit(1); } for (i = optind + 1 ; i < argc ; i++) { dofile(&u, argv[i], eflags, (optind < argc-1), plineno, pline, collseq); } urefree(&u); exit(0); }