static void load_rules( const char* argv_rules, size_t length ) { CIStream str; assert( length < 512 ); str = make_string_input_stream(argv_rules, length, FALSE); read_patterns ( str, argv_domain_name, FALSE ); cis_close(str); }
int main(int argc, char* argv[]){ char** ap; initialize_syntax(); ap = argv+1; stdout_stream = make_file_output_stream(stdout,""); stdin_stream = make_file_input_stream(stdin,NULL); output_stream = stdout_stream; if ( argc >= 3 && stricmp(*ap,"-prim") == 0 ) { CIStream ps; ap++; ps = open_input_file( *ap, FALSE ); if ( ps != NULL ) { read_patterns(ps, "", FALSE); cis_close(ps); } ap++; } else initialize_argv_domain(); do_args(ap); return (int)exit_status; }
int main(int argc, char *argv[]) { char **aargv, **eargv, *eopts; char *ep; const char *pn; long long l; unsigned int aargc, eargc, i; int c, lastc, needpattern, newarg, prevoptind; setlocale(LC_ALL, ""); #ifndef WITHOUT_NLS catalog = catopen("grep", NL_CAT_LOCALE); #endif /* Check what is the program name of the binary. In this way we can have all the funcionalities in one binary without the need of scripting and using ugly hacks. */ pn = getprogname(); if (pn[0] == 'b' && pn[1] == 'z') { filebehave = FILE_BZIP; pn += 2; } else if (pn[0] == 'x' && pn[1] == 'z') { filebehave = FILE_XZ; pn += 2; } else if (pn[0] == 'l' && pn[1] == 'z') { filebehave = FILE_LZMA; pn += 2; } else if (pn[0] == 'r') { dirbehave = DIR_RECURSE; Hflag = true; } else if (pn[0] == 'z') { filebehave = FILE_GZIP; pn += 1; } switch (pn[0]) { case 'e': grepbehave = GREP_EXTENDED; break; case 'f': grepbehave = GREP_FIXED; break; } lastc = '\0'; newarg = 1; prevoptind = 1; needpattern = 1; fileeol = '\n'; eopts = getenv("GREP_OPTIONS"); /* support for extra arguments in GREP_OPTIONS */ eargc = 0; if (eopts != NULL && eopts[0] != '\0') { char *str; /* make an estimation of how many extra arguments we have */ for (unsigned int j = 0; j < strlen(eopts); j++) if (eopts[j] == ' ') eargc++; eargv = (char **)grep_malloc(sizeof(char *) * (eargc + 1)); eargc = 0; /* parse extra arguments */ while ((str = strsep(&eopts, " ")) != NULL) if (str[0] != '\0') eargv[eargc++] = grep_strdup(str); aargv = (char **)grep_calloc(eargc + argc + 1, sizeof(char *)); aargv[0] = argv[0]; for (i = 0; i < eargc; i++) aargv[i + 1] = eargv[i]; for (int j = 1; j < argc; j++, i++) aargv[i + 1] = argv[j]; aargc = eargc + argc; } else { aargv = argv; aargc = argc; } while (((c = getopt_long(aargc, aargv, optstr, long_options, NULL)) != -1)) { switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (newarg || !isdigit(lastc)) Aflag = 0; else if (Aflag > LLONG_MAX / 10 - 1) { errno = ERANGE; err(2, NULL); } Aflag = Bflag = (Aflag * 10) + (c - '0'); break; case 'C': if (optarg == NULL) { Aflag = Bflag = 2; break; } /* FALLTHROUGH */ case 'A': /* FALLTHROUGH */ case 'B': errno = 0; l = strtoll(optarg, &ep, 10); if (errno == ERANGE || errno == EINVAL) err(2, NULL); else if (ep[0] != '\0') { errno = EINVAL; err(2, NULL); } else if (l < 0) { errno = EINVAL; err(2, "context argument must be non-negative"); } if (c == 'A') Aflag = l; else if (c == 'B') Bflag = l; else Aflag = Bflag = l; break; case 'a': binbehave = BINFILE_TEXT; break; case 'b': bflag = true; break; case 'c': cflag = true; break; case 'D': if (strcasecmp(optarg, "skip") == 0) devbehave = DEV_SKIP; else if (strcasecmp(optarg, "read") == 0) devbehave = DEV_READ; else errx(2, getstr(3), "--devices"); break; case 'd': if (strcasecmp("recurse", optarg) == 0) { Hflag = true; dirbehave = DIR_RECURSE; } else if (strcasecmp("skip", optarg) == 0) dirbehave = DIR_SKIP; else if (strcasecmp("read", optarg) == 0) dirbehave = DIR_READ; else errx(2, getstr(3), "--directories"); break; case 'E': grepbehave = GREP_EXTENDED; break; case 'e': { char *token; char *string = optarg; while ((token = strsep(&string, "\n")) != NULL) add_pattern(token, strlen(token)); } needpattern = 0; break; case 'F': grepbehave = GREP_FIXED; break; case 'f': read_patterns(optarg); needpattern = 0; break; case 'G': grepbehave = GREP_BASIC; break; case 'H': Hflag = true; break; case 'h': Hflag = false; hflag = true; break; case 'I': binbehave = BINFILE_SKIP; break; case 'i': case 'y': iflag = true; cflags |= REG_ICASE; break; case 'J': #ifdef WITHOUT_BZIP2 errno = EOPNOTSUPP; err(2, "bzip2 support was disabled at compile-time"); #endif filebehave = FILE_BZIP; break; case 'L': lflag = false; Lflag = true; break; case 'l': Lflag = false; lflag = true; break; case 'm': mflag = true; errno = 0; mlimit = mcount = strtoll(optarg, &ep, 10); if (((errno == ERANGE) && (mcount == LLONG_MAX)) || ((errno == EINVAL) && (mcount == 0))) err(2, NULL); else if (ep[0] != '\0') { errno = EINVAL; err(2, NULL); } break; case 'M': filebehave = FILE_LZMA; break; case 'n': nflag = true; break; case 'O': linkbehave = LINK_EXPLICIT; break; case 'o': oflag = true; cflags &= ~REG_NOSUB; break; case 'p': linkbehave = LINK_SKIP; break; case 'q': qflag = true; break; case 'S': linkbehave = LINK_READ; break; case 'R': case 'r': dirbehave = DIR_RECURSE; Hflag = true; break; case 's': sflag = true; break; case 'U': binbehave = BINFILE_BIN; break; case 'u': case MMAP_OPT: filebehave = FILE_MMAP; break; case 'V': #ifdef WITH_GNU printf(getstr(10), getprogname(), VERSION); #else printf(getstr(9), getprogname(), VERSION); #endif exit(0); case 'v': vflag = true; break; case 'w': wflag = true; cflags &= ~REG_NOSUB; break; case 'x': xflag = true; cflags &= ~REG_NOSUB; break; case 'X': filebehave = FILE_XZ; break; case 'z': fileeol = '\0'; break; case 'Z': filebehave = FILE_GZIP; break; case BIN_OPT: if (strcasecmp("binary", optarg) == 0) binbehave = BINFILE_BIN; else if (strcasecmp("without-match", optarg) == 0) binbehave = BINFILE_SKIP; else if (strcasecmp("text", optarg) == 0) binbehave = BINFILE_TEXT; else errx(2, getstr(3), "--binary-files"); break; case COLOR_OPT: color = NULL; if (optarg == NULL || strcasecmp("auto", optarg) == 0 || strcasecmp("tty", optarg) == 0 || strcasecmp("if-tty", optarg) == 0) { char *term; term = getenv("TERM"); if (isatty(STDOUT_FILENO) && term != NULL && strcasecmp(term, "dumb") != 0) color = init_color("01;31"); } else if (strcasecmp("always", optarg) == 0 || strcasecmp("yes", optarg) == 0 || strcasecmp("force", optarg) == 0) { color = init_color("01;31"); } else if (strcasecmp("never", optarg) != 0 && strcasecmp("none", optarg) != 0 && strcasecmp("no", optarg) != 0) errx(2, getstr(3), "--color"); cflags &= ~REG_NOSUB; break; case LABEL_OPT: label = optarg; break; case LINEBUF_OPT: lbflag = true; break; case NULL_OPT: nullflag = true; break; case R_INCLUDE_OPT: finclude = true; add_fpattern(optarg, INCL_PAT); break; case R_EXCLUDE_OPT: fexclude = true; add_fpattern(optarg, EXCL_PAT); break; case R_DINCLUDE_OPT: dinclude = true; add_dpattern(optarg, INCL_PAT); break; case R_DEXCLUDE_OPT: dexclude = true; add_dpattern(optarg, EXCL_PAT); break; case HELP_OPT: default: usage(); } lastc = c; newarg = optind != prevoptind; prevoptind = optind; } aargc -= optind; aargv += optind; /* Empty pattern file matches nothing */ if (!needpattern && (patterns == 0)) exit(1); /* Fail if we don't have any pattern */ if (aargc == 0 && needpattern) usage(); /* Process patterns from command line */ if (aargc != 0 && needpattern) { char *token; char *string = *aargv; while ((token = strsep(&string, "\n")) != NULL) add_pattern(token, strlen(token)); --aargc; ++aargv; } switch (grepbehave) { case GREP_BASIC: break; case GREP_FIXED: /* * regex(3) implementations that support fixed-string searches generally * define either REG_NOSPEC or REG_LITERAL. Set the appropriate flag * here. If neither are defined, GREP_FIXED later implies that the * internal literal matcher should be used. Other cflags that have * the same interpretation as REG_NOSPEC and REG_LITERAL should be * similarly added here, and grep.h should be amended to take this into * consideration when defining WITH_INTERNAL_NOSPEC. */ #if defined(REG_NOSPEC) cflags |= REG_NOSPEC; #elif defined(REG_LITERAL) cflags |= REG_LITERAL; #endif break; case GREP_EXTENDED: cflags |= REG_EXTENDED; break; default: /* NOTREACHED */ usage(); } #ifndef WITHOUT_FASTMATCH fg_pattern = grep_calloc(patterns, sizeof(*fg_pattern)); #endif r_pattern = grep_calloc(patterns, sizeof(*r_pattern)); /* Don't process any patterns if we have a blank one */ #ifdef WITH_INTERNAL_NOSPEC if (!matchall && grepbehave != GREP_FIXED) { #else if (!matchall) { #endif /* Check if cheating is allowed (always is for fgrep). */ for (i = 0; i < patterns; ++i) { #ifndef WITHOUT_FASTMATCH /* * Attempt compilation with fastmatch regex and * fallback to regex(3) if it fails. */ if (fastncomp(&fg_pattern[i], pattern[i].pat, pattern[i].len, cflags) == 0) continue; #endif c = regcomp(&r_pattern[i], pattern[i].pat, cflags); if (c != 0) { regerror(c, &r_pattern[i], re_error, RE_ERROR_BUF); errx(2, "%s", re_error); } } } if (lbflag) setlinebuf(stdout); if ((aargc == 0 || aargc == 1) && !Hflag) hflag = true; if (aargc == 0 && dirbehave != DIR_RECURSE) exit(!procfile("-")); if (dirbehave == DIR_RECURSE) c = grep_tree(aargv); else for (c = 0; aargc--; ++aargv) { if ((finclude || fexclude) && !file_matching(*aargv)) continue; c+= procfile(*aargv); } #ifndef WITHOUT_NLS catclose(catalog); #endif /* Find out the correct return value according to the results and the command line option. */ exit(c ? (file_err ? (qflag ? 0 : 2) : 0) : (file_err ? 2 : 1)); }
main(int argc, char *argv[]) { int c, done, i, j, h, l, len; unsigned char *q; int hyf[LINE_LENGTH]; int hif[MAXPAT]; unsigned char syllable[LINE_LENGTH]; char *patterns_file = NULL, *prog_name; struct pattern *p; void syllabe(int, unsigned char *, unsigned char *); prog_name = argv[0]; while (--argc > 0 && (*++argv)[0] == '-') { done=0; while ((!done) && (c = *++argv[0])) /* allow -bcK like options */ switch (c) { case 'd': if (*++argv[0] == '\0') { argc--; argv++; } logging = atoi(argv[0]); done = 1; break; case 'L': if (*++argv[0] == '\0') { argc--; argv++; } leftmin = atoi(argv[0]); done = 1; break; case 'R': if (*++argv[0] == '\0') { argc--; argv++; } rightmin = atoi(argv[0]); done = 1; break; default: fprintf(stderr, "%s: %c illegal option\n", prog_name, c); exit(1); } } if (argc != 1) usage(prog_name); patterns_file = argv[0]; linep = line; read_patterns(patterns_file); *linep = '.'; while (gets(linep+1)) { /* look first for an exception */ i = search_exception(linep+1); if (i >= 0) { j=0; l = exclusive_length(exc[i]); for (q=exc[i]; *q != '\0'; q++) { if (*q != '-') { putchar(*q); j++; } else if (j>=leftmin && j <= l-rightmin) putchar('-'); } putchar('\n'); continue; } len = strlen(linep+1); line[len+1] = '.'; line[len+2] = '\0'; for (i=0; i<=len+2; i++) hyf[i] = 0; for (i=0; i<=len; i++) { syllable[0] = tolow[line[i]]; /* look for single alfanumeric letter first */ syllable[1] = '\0'; if (alpha[syllable[0]]) { j = key(syllable); if (j >= 0 && ((p = entry[j]) != NULL)) { unpackhyfs(1, hif, p->hyfens); hyf[i] = max(hyf[i], hif[0]); hyf[i+1] = max(hyf[i+1], hif[1]); if (logging & PATTERNS) { showhyfs(syllable, hif); putchar('\n'); } } } /* loop through list of patterns and match them with current word */ syllable[1] = tolow[line[i+1]]; syllable[2] = '\0'; j = key(syllable); if (j < 0 || (p = entry[j]) == NULL) continue; do { l = strlen((char *) p->name); if (equal(&line[i+2], p->name, l) == 0) { strcpy((char *) &syllable[2], (char *) p->name); unpackhyfs(l+2, hif, p->hyfens); for (h=0; h <= strlen((char *) syllable); h++) hyf[i+h] = max(hyf[i+h], hif[h]); if (logging & PATTERNS) { showhyfs(syllable, hif); putchar('\n'); } } } while (p=p->next); } if (logging & PATTERNS) { showhyfs(line, hyf); putchar('\n'); } hyphenate(line, hyf); } }
const unsigned char* do_action( const unsigned char* action, CIStream* args, COStream out) { const unsigned char* as; unsigned char ac; int argn = 0; as = action; if ( as != NULL ) for ( ; ; ) { ac = *as++; switch (ac) { case PT_END: return as-1; case PT_SEPARATOR: return as; case PT_PUT_ARG: { CIStream arg = args[ (*as++) - 1 ]; cis_rewind(arg); cos_copy_input_stream(out,arg); break; } case PT_ONE_OPT: cos_putch(out,arg_char); break; case PT_DOMAIN: { CIStream inbuf; Pattern save_rule = current_rule; #if MAX_DOMAINS < 256 int domain = *as++ - 1; #else /* Get domain index as 14 bit little endian number */ int domain = ((unsigned char)*as++)&0x7f; domain = ((((unsigned char)*as++)&0x7f)<<7) | domain; #endif if ( as[0] == PT_VAR1 || ( as[0] == PT_OP && ( as[1] == OP_VAR || as[1] == OP_VAR_DFLT ) ) ) { /* for safety, copy the variable's value in case it is changed during translation. */ COStream outbuf; outbuf = make_buffer_output_stream(); as = do_action( as, args, outbuf ); inbuf = convert_output_to_input( outbuf ); } else /* optimized operand access */ inbuf = function_operand( &as, args ); #ifdef TRACE if ( trace_switch ) { int n; fprintf( stderr, "%12ld,%2d ", cis_line(input_stream), cis_column(input_stream)); for ( n = trace_indent ; n > 0 ; n-- ) fputc(' ',stderr); if ( cis_is_file(inbuf) ) { const char* inpath = cis_pathname(inbuf); if ( inpath == NULL ) inpath = "-"; fprintf( stderr, "@%s{@read{%s}}\n", domains[domain]->name, inpath); } else fprintf( stderr, "@%s{%.60s}\n", domains[domain]->name, cis_whole_string(inbuf)); ++trace_indent; } #endif if ( !translate( inbuf, domains[domain], out, NULL ) && cis_is_file(inbuf) && exit_status < EXS_FAIL ) exit_status = EXS_FAIL; #ifdef TRACE if ( trace_switch ) { --trace_indent; } #endif current_rule = save_rule; cis_close(inbuf); break; } case PT_VAR1: { char vname[2]; vname[0] = *as++; vname[1] = '\0'; put_var(out, vname, FALSE); break; } case PT_LINE: cos_freshline(out); break; case PT_MATCHED_TEXT: do_action( current_rule->pattern, args, out ); break; case PT_SPECIAL_ARG: #if MAX_DOMAINS >= 256 /* advance one more since 2 bytes for domain index */ case PT_RECUR: #endif as++; case PT_REGEXP: #if MAX_DOMAINS < 256 case PT_RECUR: #endif as++; case PT_MATCH_ANY: case PT_MATCH_ONE: { /* these will be encountered only when replaying the template as $0 */ CIStream arg = args[ argn++ ]; cis_rewind(arg); cos_copy_input_stream(out,arg); break; } case PT_AUX: as++; break; case PT_OP: { CIStream inbuf = NULL; enum Operators ac; ac = (enum Operators)*as++; switch(ac) { case OP_UNDEFINE: case OP_DEFINE: { inbuf = function_operand( &as, args ); read_patterns(inbuf, "", ac==OP_UNDEFINE); break; } case OP_SUBST: { int d; CIStream arg; Pattern save_rule = current_rule; arg = function_operand( &as, args ); d = read_patterns(arg," temp ",FALSE); inbuf = function_operand( &as, args ); translate ( inbuf, domains[d], out, NULL ); current_rule = save_rule; delete_domain(d); cis_close(arg); break; } case OP_VAR: { inbuf = function_operand( &as, args ); put_var(out, cis_whole_string(inbuf), FALSE ); break; } case OP_VAR_DFLT: { inbuf = function_operand( &as, args ); /* variable name */ if ( put_var(out, cis_whole_string(inbuf), TRUE ) ) as = skip_action(as); /* skip default value */ else as = do_action( as, args, out ); /* output default */ break; } case OP_SET: { CIStream name; name = function_operand( &as, args ); inbuf = function_operand( &as, args ); set_var( cis_whole_string(name), cis_whole_string(inbuf), cis_length(inbuf) ); cis_close(name); break; } case OP_BIND: { CIStream name; name = function_operand( &as, args ); inbuf = function_operand( &as, args ); bind_var( cis_whole_string(name), cis_whole_string(inbuf), cis_length(inbuf) ); cis_close(name); break; } case OP_UNBIND: { CIStream name; name = function_operand( &as, args ); unbind_var( cis_whole_string(name) ); cis_close(name); break; } case OP_APPEND: { CIStream name; name = function_operand( &as, args ); inbuf = function_operand( &as, args ); append_var( cis_whole_string(name), cis_whole_string(inbuf), cis_length(inbuf) ); cis_close(name); break; } case OP_INCR: case OP_DECR: { CIStream name; name = function_operand( &as, args ); incr_var( cis_whole_string(name), ac==OP_DECR? -1 : 1 ); cis_close(name); break; } case OP_GETENV: case OP_GETENV_DEFAULT: { CIStream dbuf = NULL; char* value; inbuf = function_operand( &as, args ); if ( ac == OP_GETENV_DEFAULT ) dbuf = function_operand( &as, args ); value = getenv(cis_whole_string(inbuf)); if ( value == NULL ) cos_copy_input_stream(out, dbuf); else cos_puts(out, value); cis_close(dbuf); break; } case OP_ERR: { static COStream err_stream = NULL; if ( err_stream == NULL ) err_stream = make_file_output_stream(stderr,"stderr"); as = do_action( as, args, err_stream ); break; } case OP_OUT: { as = do_action( as, args, output_stream ); break; } case OP_PATH: case OP_FILE: { const char* path = cis_pathname(input_stream); if ( path != NULL ) { if ( ac == OP_FILE ) path = pathname_name_and_type(path); cos_puts(out, path); } break; } case OP_OUTFILE: { const char* opath; opath = cos_pathname(out); if ( opath == NULL ) opath = cos_pathname(output_stream); cos_puts(out, opath); break; } case OP_LINE: { put_number(out, cis_line(input_stream)); break; } case OP_COL: { put_number(out, cis_column(input_stream)); break; } case OP_OUTCOL: { put_number(out, cos_column(output_stream)); break; } case OP_HELP: usage(); break; case OP_VERSION: cos_puts(out, Version); break; case OP_DATE: case OP_TIME: { time_t now; struct tm* ts; char tbuf [12]; now = time(NULL); ts = localtime(&now); if ( ac == OP_TIME ) sprintf(tbuf, "%02d:%02d:%02d", ts->tm_hour, ts->tm_min, ts->tm_sec); else sprintf(tbuf, "%02d/%02d/%d", ts->tm_mon + 1, ts->tm_mday, 1900 + ts->tm_year); cos_puts(out, tbuf); break; } case OP_DATIME: { time_t now; now = time(NULL); put_datime( out, &now ); break; } case OP_MODTIME: { time_t mtime; mtime = cis_mod_time(input_stream); if ( mtime != 0 ) put_datime( out, &mtime ); break; } case OP_PROBE: { inbuf = function_operand( &as, args ); cos_putch(out, probe_pathname(cis_whole_string(inbuf))); break; } case OP_READ: { const char* pathname; CIStream in; inbuf = function_operand( &as, args ); pathname = cis_whole_string(inbuf); close_output(pathname); in = open_input_file(pathname,binary); cos_copy_input_stream(out, in); cis_close(in); break; } case OP_WRITE: { COStream oldout; const char* pathname; oldout = output_stream; inbuf = function_operand( &as, args ); pathname = cis_whole_string(inbuf); output_stream = find_output_file(pathname,TRUE); as = do_action( as, args, output_stream ); output_stream = oldout; break; } case OP_CLOSE: { inbuf = function_operand( &as, args ); close_output(cis_whole_string(inbuf)); break; } case OP_COMBINEPATH: case OP_MERGEPATH: { CIStream dir; CIStream name; CIStream typ; dir = function_operand( &as, args ); name = function_operand( &as, args ); typ = function_operand( &as, args ); merge_pathnames( out, ac==OP_COMBINEPATH, cis_whole_string(dir), cis_whole_string(name), cis_whole_string(typ) ); cis_close(dir); cis_close(name); cis_close(typ); break; } case OP_RELPATH: { CIStream dir; dir = function_operand( &as, args ); inbuf = function_operand( &as, args ); cos_puts( out, relative_pathname(cis_whole_string(dir), cis_whole_string(inbuf)) ); cis_close(dir); break; } case OP_EXP_WILD: { inbuf = function_operand( &as, args ); expand_wildcard ( cis_whole_string(inbuf), out ); break; } case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: case OP_MOD: case OP_AND: case OP_OR: { long x,y,z; x = numeric_operand( &as, args ); y = numeric_operand( &as, args ); switch(ac) { case OP_ADD: z = x + y; break; case OP_SUB: z = x - y; break; case OP_MUL: z = x * y; break; case OP_DIV: z = x / y; break; case OP_MOD: z = x % y; break; case OP_AND: z = x & y; break; case OP_OR: z = x | y; break; default: /* can't happen; just to avoid compiler warning */ assert(FALSE); z = 0; break; } put_number(out,z); break; } case OP_NOT: put_number(out, ~ numeric_operand( &as, args ) ); break; case OP_RADIX: { int from, to; unsigned long value; char* string; char* end; const char* fmt; char buf[24]; /* enough for 64 bits in octal */ from = (int)numeric_operand( &as, args ); to = (int)numeric_operand( &as, args ); inbuf = function_operand( &as, args ); string = cis_whole_string(inbuf); value = strtoul( string, &end, from ); if ( *end != '\0' ) input_error ( input_stream, EXS_NUM, "Invalid argument for radix %d conversion: \"%.99s\"\n", from, string); if ( to == 8 ) fmt = "%lo"; else if ( to == 16 ) fmt = "%lX"; else { if ( to != 10 ) input_error ( input_stream, EXS_NUM, "Unsupported radix: %d\n", to); while ( isspace(string[0]) ) string++; fmt = (string[0]=='-') ? "%ld" : "%lu"; } sprintf(buf, fmt, value); cos_puts(out, buf); break; } case OP_STR_CMP: case OP_STRI_CMP: { /* string comparison */ CIStream x = function_operand( &as, args ); CIStream y = function_operand( &as, args ); const char* xs = cis_whole_string(x); const char* ys = cis_whole_string(y); int cmp; cmp = ac == OP_STRI_CMP ? stricmp(xs, ys) : strcmp(xs, ys); cis_close(x); cis_close(y); as = do_cmp( cmp, as, args, out); break; } case OP_NUM_CMP: { /* numeric comparison */ long x = numeric_operand( &as, args ); long y = numeric_operand( &as, args ); int cmp; if ( x < y ) cmp = -1; else if ( x == y ) cmp = 0; else cmp = 1; as = do_cmp( cmp, as, args, out); break; } case OP_LENGTH: { inbuf = function_operand( &as, args ); put_number(out, cis_length(inbuf)); break; } case OP_TAB: { int col; col = (int)numeric_operand( &as, args ); cos_spaces(out, col - (int)cos_column(out)); break; } case OP_WRAP: { unsigned length; unsigned col; inbuf = function_operand( &as, args ); length = cis_length(inbuf); col = cos_column(out); if ( ( ((int)(col + length)) > wrap_column && col > wrap_indent_length ) || ( col <= 1 && length > 0 ) ) { cos_freshline(out); cos_puts(out, wrap_indent); skip_whitespace(inbuf); } cos_copy_input_stream(out, inbuf); break; } case OP_SET_WRAP: { wrap_column = (int)numeric_operand( &as, args ); inbuf = function_operand( &as, args ); if ( wrap_indent != NULL ) free(wrap_indent); wrap_indent_length = cis_length(inbuf); wrap_indent = str_dup_len( cis_whole_string(inbuf), wrap_indent_length ); break; } case OP_RIGHT: case OP_LEFT: case OP_CENTER: { /* justify value in fixed-length field */ int field_length, string_length, left_pad, right_pad; field_length = (int)numeric_operand( &as, args ); inbuf = function_operand( &as, args ); string_length = cis_length(inbuf); left_pad = field_length - string_length; right_pad = 0; if ( left_pad < 0 ) left_pad = 0; if ( ac == OP_LEFT ) { right_pad = left_pad; left_pad = 0; } else if ( ac == OP_CENTER ) { left_pad = left_pad / 2; right_pad = field_length - string_length - left_pad; } cos_spaces(out, left_pad); cos_copy_input_stream(out, inbuf); cos_spaces(out, right_pad); break; } case OP_FILL_RIGHT: case OP_FILL_LEFT: case OP_FILL_CENTER: { /* justify value in fixed-length field */ int field_length, string_length, left_pad, right_pad; CIStream background; int i; background = function_operand( &as, args ); field_length = cis_length(background); inbuf = function_operand( &as, args ); string_length = cis_length(inbuf); left_pad = field_length - string_length; right_pad = 0; if ( left_pad < 0 ) left_pad = 0; if ( ac == OP_FILL_LEFT ) { right_pad = left_pad; left_pad = 0; } else if ( ac == OP_FILL_CENTER ) { left_pad = left_pad / 2; right_pad = field_length - string_length - left_pad; } else assert( ac == OP_FILL_RIGHT ); for ( i = left_pad ; i > 0 ; i-- ) cos_putch(out, cis_getch(background)); cos_copy_input_stream(out, inbuf); if ( right_pad > 0 ) { for ( i = string_length ; i > 0 ; i-- ) (void)cis_getch(background); cos_copy_input_stream(out, background); } cis_close(background); break; } case OP_SUBSTRING: { int skip_length, result_length, string_length; skip_length = (int)numeric_operand( &as, args ); result_length = (int)numeric_operand( &as, args ); inbuf = function_operand( &as, args ); string_length = cis_length(inbuf); if ( skip_length <= string_length ) { if ( skip_length < 0 ) skip_length = 0; if ( (skip_length + result_length) > string_length ) result_length = string_length - skip_length; cos_put_len(out, cis_whole_string(inbuf) + skip_length, result_length); } break; } case OP_DOWNCASE: case OP_UPCASE: { int cc; inbuf = function_operand( &as, args ); while ( (cc = cis_getch(inbuf)) != EOF ) cos_putch(out, ac==OP_DOWNCASE ? tolower(cc) : toupper(cc) ); break; } case OP_CHARINT: inbuf = function_operand( &as, args ); put_number(out, cis_getch(inbuf)); break; case OP_INTCHAR: cos_putch(out, (char)numeric_operand( &as, args )); break; case OP_REVERSE: { int len; const char* start; const char* ip; inbuf = function_operand( &as, args ); len = cis_length(inbuf); start = cis_whole_string(inbuf); for ( ip = start+len-1 ; ip >= start ; ip-- ) cos_putch(out, *ip); break; } case OP_SHELL: { const char* command; inbuf = function_operand( &as, args ); command = cis_whole_string(inbuf); fflush(stdout); if ( system( command ) < 0 ) { input_error ( input_stream, EXS_SHELL, "Failed shell command \"%.20s...\":\n", command ); perror("system"); } break; } case OP_EXIT: translation_status = Translate_Exited; break; case OP_FAIL: translation_status = Translate_Failed; break; case OP_END_OR_FAIL: /* ideally this should be testing whether the input stream has been advanced, but that is not so easy. */ translation_status = ( cis_out_length(out) == 0 )? Translate_Failed : Translate_Exited; break; case OP_EXIT_STATUS: exit_status = (Exit_States)(int)numeric_operand( &as, args ); break; case OP_ABORT: exit((int)(exit_status > EXS_FAIL ? exit_status : EXS_FAIL )); break; case OP_GET_SWITCH: case OP_SET_SWITCH: { const char* name; int* valpt; inbuf = function_operand( &as, args ); name = cis_whole_string(inbuf); valpt = find_switch(name); if ( valpt == NULL ) { input_error(input_stream, EXS_UNDEF, "Undefined switch name \"%.99s\"\n", name ); if ( ac == OP_SET_SWITCH ) (void)numeric_operand( &as, args ); } else { if ( ac == OP_SET_SWITCH ) *valpt = (int)numeric_operand( &as, args ); else put_number( out, *valpt ); } break; } case OP_SET_PARM: { const char* name; CIStream val; inbuf = function_operand( &as, args ); name = cis_whole_string(inbuf); val = function_operand( &as, args ); if ( !set_parm( name, cis_whole_string(val) ) ) input_error(input_stream, EXS_UNDEF, "Undefined parameter name \"%.99s\"\n", name ); cis_close(val); break; } case OP_SYNTAX: { const char* type; const char* charset; CIStream val; inbuf = function_operand( &as, args ); val = function_operand( &as, args ); charset = cis_whole_string(val); for ( type = cis_whole_string(inbuf) ; *type != '\0' ; type++ ) { const char* chars; char c[2]; if ( type[1] == '\0' ) chars = charset; else { c[0] = *charset++; c[1] = '\0'; chars = c; } if ( !set_syntax(type[0], chars) ) input_error(input_stream, EXS_UNDEF, "Undefined syntax type \"%.99s\"\n", type ); } cis_close(val); break; } case OP_DEFAULT_SYNTAX: initialize_syntax(); break; #ifndef MSDOS case OP_LOCALE: { const char* lname; inbuf = function_operand( &as, args ); lname = cis_whole_string(inbuf); if ( setlocale(LC_ALL, lname) == NULL ) input_error(input_stream, EXS_UNDEF, "Undefined locale \"%.99s\"\n", lname ); break; } #endif case OP_REPEAT: { long n = numeric_operand( &as, args ); if ( n <= 0 ) as = skip_action(as); else { const unsigned char* start = as; for ( ; n > 0 ; n-- ) as = do_action( start, args, out ); } break; } case OP_QUOTE: { inbuf = function_operand( &as, args ); quoted_copy( inbuf, out ); break; } default: fprintf(stderr, "Undefined op in action: %d\n", (int)ac); break; } /* end switch on ops */ cis_close(inbuf); break; } /* end PT_OP */ case PT_WORD_DELIM: case PT_ID_DELIM: /* Ignore if in expansion of "$0" */ if ( current_rule == NULL || action != current_rule->pattern ) { /* output a space if needed as a delimiter */ int prevch = cos_prevch(out); if ( prevch != EOF ) if ( ac == PT_ID_DELIM ? isident(prevch) : isalnum(prevch) ) cos_putch(out,' '); } break; #if 0 /* not needed now */ case PT_ARG_DELIM: if ( cos_prevch(out) != Arg_Delim ) cos_putch(out,Arg_Delim); break; #endif case PT_SPACE: { /* output a space if the last character is not white space */ int prevch = cos_prevch(out); if ( !isspace(prevch) ) cos_putch(out,' '); break; } case PT_SKIP_WHITE_SPACE: break; case PT_QUOTE: /* use next character literally */ ac = *as++; /* and fall-through */ default: cos_putch(out, ac); } /* end switch ac */ } /* end for */ /* can't ever get here, but return to avoid Gnu compiler warning. */ return as; }
int main(int argc, char **argv) { /** * Create binary searches predefined by file type (look into its header). For example: all the PDF files */ DirTreeReader *dtr {}; std::vector<std::bitset<8>> vecPat; unsigned char optField = read_opt(argc, argv, "fl"); if ((optField & OPTIONS::INVALID) == OPTIONS::INVALID) { show_usages(argv[0]); exit(EXIT_FAILURE); } else if(((optField & OPTIONS::NONE) == OPTIONS::NONE) && argc == 3) { if (read_patterns(&vecPat, argv[2]) == -1) { show_usages(argv[0]); exit(EXIT_FAILURE); } dtr = new DirTreeReader(argv[1]); } else if(((optField & OPTIONS::NONE) == OPTIONS::NONE) && argc == 4) { if (read_patterns(&vecPat, argv[3]) == -1) { show_usages(argv[0]); exit(EXIT_FAILURE); } dtr = new DirTreeReader(argv[2]); } else { show_usages(argv[0]); exit(EXIT_FAILURE); } std::cout << "Number of CPU cores: " << std::thread::hardware_concurrency() << std::endl; std::vector<std::string> files = dtr->loadFiles(); std::cout << "Total files read: " << dtr->getTotalFiles() << std::endl; int offset { -1 }; std::future<int> fut {}; BinFinder bf(files.at(0)); for (uint i = 0; i < files.size(); ++i) { bf.setFile(files.at(i)); if ((optField & OPTIONS::CURR_FILE) == OPTIONS::CURR_FILE) std::cout << "Looking into " << files.at(i) << std::endl; if ((optField & OPTIONS::CREAT_LOG) == OPTIONS::CREAT_LOG) fut = std::async(std::launch::async, &BinFinder::containsInFile, &bf, vecPat, 1, true); // std::launch::async force async to create a thread else fut = std::async(std::launch::async, &BinFinder::containsInFile, &bf, vecPat, 1, false); // std::launch::async force async to create a thread offset = fut.get(); if (offset > -1) std::cout << "Found in: " << files.at(i) << " at offset: " << std::hex << "0x" << offset << std::endl; } if (dtr) delete dtr; exit(EXIT_SUCCESS); }