int parse_section() { match_line(SECTION_HEADER); match_line(SECTION_NAME); match_line(SECTION_NUMBER); parse_item(); output("};\n"); flush_cache(CACHE1); return 0; }
int parse_item_item_item() { match_line(ITEM_ITEM_ITEM_HEADER); match_line(ITEM_ITEM_ITEM_FIELD); while(1) { switch (looknext) { case ITEM_ITEM_ITEM_FIELD: match_line(ITEM_ITEM_ITEM_FIELD); break; default: goto _end; } } _end: return 0; }
static int find_mtd(char *label, char *dev, size_t len) { int found; FILE *fp; char line[64]; fp = fopen("/proc/mtd", "r"); if (!fp) return 0; found = match_line(label, line, sizeof(line), fp); fclose(fp); if (found) { char *ptr; ptr = strchr(line, ':'); if (!ptr) { found = 0; } else { *ptr = 0; snprintf(dev, len, "/dev/%s", line); } } return found; }
/** match_stdin * Reads up to the maximum number of lines from standard input * * Return Value: * int - the number of matches found or the number of lines without matches * if the -r flag was used * struct Globals *gl - the "global" variables for this search */ int match_stdin(struct counters *counter, struct Globals *gl){ char *input_line; int count = 0; int status; int matches = 0; unsigned int my_flags; unsigned int num_chars; int max_lines; my_flags = gl->my_flags; num_chars = gl->num_chars; max_lines = gl->max_lines; input_line = calloc(sizeof(char), num_chars); counter->files_read++; while(matches != max_lines && fgets(input_line, num_chars, stdin) != NULL){ count++; trim_line(input_line); status = match_line(input_line, &counter, gl); if(status == MATCH && (my_flags&REVERSE_SELECTION) != REVERSE_SELECTION){ /* Increments the match counter if a match was found and the reverse flag was not chosen */ if((my_flags&SUMMARY) != SUMMARY){ /* Prints out the line if the summary flag was not chosen */ pthread_mutex_lock(&mu); /* Since the server does not read from standard in, no check needs to be done here. */ fprintf(stdout, "%d: %s\n", count, input_line); pthread_mutex_unlock(&mu); } matches++; }else if(status == NO_MATCH && (my_flags&REVERSE_SELECTION) == REVERSE_SELECTION){ /* Increments the match counter if a match was not found and the reverse flag was chosen */ if((my_flags&SUMMARY) != SUMMARY){ /* Prints out the line if the summary flag was not chosen */ pthread_mutex_lock(&mu); /* Since the server does not read from standard in, no check needs to be done here. */ fprintf(stdout, "%d: %s\n", count, input_line); pthread_mutex_unlock(&mu); } matches++; } } counter->lines_read += count; counter->lines_matched += matches; counter->bytes_read += ftell(stdin); return matches; /*match_stdin*/ }
int parse_item_item() { match_line(ITEM_ITEM_HEADER); match_line(ITEM_ITEM_FIELD); while(1) { switch (looknext) { case ITEM_ITEM_FIELD: match_line(ITEM_ITEM_FIELD); break; case ITEM_ITEM_ITEM_HEADER: parse_item_item_item(); default: goto _end; } } _end: output_cache(CACHE2, "\t\t};\n", 5); flush_cache(CACHE3); return 0; }
static int is_mounted(char *label) { FILE *fp; int match; char line[64]; fp = fopen("/proc/mounts", "r"); if (!fp) return 1; match = match_line(label, line, sizeof(line), fp); fclose(fp); return match; }
/** * XXX: we don't actually do floyd */ int tga2msx_scr2_tiles() { uint16_t x, y, j; uint16_t yy, qe; struct scr2 *dst = image_out_scr2; for (y = 0; y < (tga.height + 7) >> 3; y++) { for (x = 0; x < (tga.width + 7 ) >> 3; x++) { /* process 8x8 pixel block */ for (j = 0; j < 8; j++) { yy = ((y << 3) | j); *dst++ = match_line(x, yy); } } } return 0; }
/** match_file * Reads up to the maximum number of lines from standard input * * Parameters: * FILE *fptr - the file pointer * struct Filename *file - the names associated with the file * struct Globals *gl - the "global" variables for this search * Return Value: * int - the number of matches found or the number of lines without matches * if the -r flag was used */ int match_file(FILE *fptr, struct Filename *file, struct Globals *gl){ char *input_line; int count = 0; int status; int matches = 0; unsigned int my_flags; unsigned int num_chars; int max_lines; my_flags = gl->my_flags; num_chars = gl->num_chars; max_lines = gl->max_lines; input_line = calloc(sizeof(char), num_chars); file->counters->files_read++; while(matches != max_lines && fgets(input_line, num_chars, fptr) != NULL){ count++; trim_line(input_line); status = match_line(input_line, &(file->counters), gl); if(status == MATCH && (my_flags&REVERSE_SELECTION) != REVERSE_SELECTION){ /* Increments the match counter if a match was found and the reverse flag was not chosen */ if((my_flags&SUMMARY) != SUMMARY){ /* Prints out the line if the summary flag was not chosen */ pthread_mutex_lock(&mu); if(gl->is_network){ char *output; output = calloc(sizeof(char), gl->path_max); sprintf(output, "%s,%d: %s\n", file->realptr, count, input_line); write_output_line(output, gl); free(output); } else{ fprintf(stdout, "%s,%d: %s\n", file->realptr, count, input_line); } pthread_mutex_unlock(&mu); } matches++; }else if(status == NO_MATCH && (my_flags&REVERSE_SELECTION) == REVERSE_SELECTION){ /* Increments the match counter if a match was not found and the reverse flag was chosen */ if((my_flags&SUMMARY) != SUMMARY){ /* Prints out the line if the summary flag was not chosen */ pthread_mutex_lock(&mu); if(gl->is_network){ char *output; output = calloc(sizeof(char), gl->path_max); sprintf(output, "%s,%d: %s\n", file->realptr, count, input_line); write_output_line(output, gl); free(output); } else{ fprintf(stdout, "%s,%d: %s\n", file->realptr, count, input_line); } pthread_mutex_unlock(&mu); } matches++; } } file->counters->lines_read += count; file->counters->lines_matched += matches; file->counters->bytes_read += ftell(fptr); return matches; /*match_file*/ }
static int grep_buffer_1(struct grep_opt *opt, const char *name, char *buf, unsigned long size, int collect_hits) { char *bol = buf; unsigned long left = size; unsigned lno = 1; unsigned last_hit = 0; int binary_match_only = 0; unsigned count = 0; int try_lookahead = 0; enum grep_context ctx = GREP_CONTEXT_HEAD; xdemitconf_t xecfg; opt->last_shown = 0; if (!opt->output) opt->output = std_output; if (buffer_is_binary(buf, size)) { switch (opt->binary) { case GREP_BINARY_DEFAULT: binary_match_only = 1; break; case GREP_BINARY_NOMATCH: return 0; /* Assume unmatch */ break; default: break; } } memset(&xecfg, 0, sizeof(xecfg)); if (opt->funcname && !opt->unmatch_name_only && !opt->status_only && !opt->name_only && !binary_match_only && !collect_hits) { struct userdiff_driver *drv = userdiff_find_by_path(name); if (drv && drv->funcname.pattern) { const struct userdiff_funcname *pe = &drv->funcname; xdiff_set_find_func(&xecfg, pe->pattern, pe->cflags); opt->priv = &xecfg; } } try_lookahead = should_lookahead(opt); while (left) { char *eol, ch; int hit; /* * look_ahead() skips quicly to the line that possibly * has the next hit; don't call it if we need to do * something more than just skipping the current line * in response to an unmatch for the current line. E.g. * inside a post-context window, we will show the current * line as a context around the previous hit when it * doesn't hit. */ if (try_lookahead && !(last_hit && lno <= last_hit + opt->post_context) && look_ahead(opt, &left, &lno, &bol)) break; eol = end_of_line(bol, &left); ch = *eol; *eol = 0; if ((ctx == GREP_CONTEXT_HEAD) && (eol == bol)) ctx = GREP_CONTEXT_BODY; hit = match_line(opt, bol, eol, ctx, collect_hits); *eol = ch; if (collect_hits) goto next_line; /* "grep -v -e foo -e bla" should list lines * that do not have either, so inversion should * be done outside. */ if (opt->invert) hit = !hit; if (opt->unmatch_name_only) { if (hit) return 0; goto next_line; } if (hit) { count++; if (opt->status_only) return 1; if (binary_match_only) { opt->output(opt, "Binary file ", 12); output_color(opt, name, strlen(name), opt->color_filename); opt->output(opt, " matches\n", 9); return 1; } if (opt->name_only) { show_name(opt, name); return 1; } /* Hit at this line. If we haven't shown the * pre-context lines, we would need to show them. * When asked to do "count", this still show * the context which is nonsense, but the user * deserves to get that ;-). */ if (opt->pre_context) show_pre_context(opt, name, buf, bol, lno); else if (opt->funcname) show_funcname_line(opt, name, buf, bol, lno); if (!opt->count) show_line(opt, bol, eol, name, lno, ':'); last_hit = lno; } else if (last_hit && lno <= last_hit + opt->post_context) { /* If the last hit is within the post context, * we need to show this line. */ show_line(opt, bol, eol, name, lno, '-'); } next_line: bol = eol + 1; if (!left) break; left--; lno++; } if (collect_hits) return 0; if (opt->status_only) return 0; if (opt->unmatch_name_only) { /* We did not see any hit, so we want to show this */ show_name(opt, name); return 1; } xdiff_clear_find_func(&xecfg); opt->priv = NULL; /* NEEDSWORK: * The real "grep -c foo *.c" gives many "bar.c:0" lines, * which feels mostly useless but sometimes useful. Maybe * make it another option? For now suppress them. */ if (opt->count && count) { char buf[32]; output_color(opt, name, strlen(name), opt->color_filename); output_sep(opt, ':'); snprintf(buf, sizeof(buf), "%u\n", count); opt->output(opt, buf, strlen(buf)); } return !!last_hit; }
static int grep_source_1(struct grep_opt *opt, struct grep_source *gs, int collect_hits) { char *bol; unsigned long left; unsigned lno = 1; unsigned last_hit = 0; int binary_match_only = 0; unsigned count = 0; int try_lookahead = 0; int show_function = 0; struct userdiff_driver *textconv = NULL; enum grep_context ctx = GREP_CONTEXT_HEAD; xdemitconf_t xecfg; if (!opt->output) opt->output = std_output; if (opt->pre_context || opt->post_context || opt->file_break || opt->funcbody) { /* Show hunk marks, except for the first file. */ if (opt->last_shown) opt->show_hunk_mark = 1; /* * If we're using threads then we can't easily identify * the first file. Always put hunk marks in that case * and skip the very first one later in work_done(). */ if (opt->output != std_output) opt->show_hunk_mark = 1; } opt->last_shown = 0; if (opt->allow_textconv) { grep_source_load_driver(gs); /* * We might set up the shared textconv cache data here, which * is not thread-safe. */ grep_attr_lock(); textconv = userdiff_get_textconv(gs->driver); grep_attr_unlock(); } /* * We know the result of a textconv is text, so we only have to care * about binary handling if we are not using it. */ if (!textconv) { switch (opt->binary) { case GREP_BINARY_DEFAULT: if (grep_source_is_binary(gs)) binary_match_only = 1; break; case GREP_BINARY_NOMATCH: if (grep_source_is_binary(gs)) return 0; /* Assume unmatch */ break; case GREP_BINARY_TEXT: break; default: die("bug: unknown binary handling mode"); } } memset(&xecfg, 0, sizeof(xecfg)); opt->priv = &xecfg; try_lookahead = should_lookahead(opt); if (fill_textconv_grep(textconv, gs) < 0) return 0; bol = gs->buf; left = gs->size; while (left) { char *eol, ch; int hit; /* * look_ahead() skips quickly to the line that possibly * has the next hit; don't call it if we need to do * something more than just skipping the current line * in response to an unmatch for the current line. E.g. * inside a post-context window, we will show the current * line as a context around the previous hit when it * doesn't hit. */ if (try_lookahead && !(last_hit && (show_function || lno <= last_hit + opt->post_context)) && look_ahead(opt, &left, &lno, &bol)) break; eol = end_of_line(bol, &left); ch = *eol; *eol = 0; if ((ctx == GREP_CONTEXT_HEAD) && (eol == bol)) ctx = GREP_CONTEXT_BODY; hit = match_line(opt, bol, eol, ctx, collect_hits); *eol = ch; if (collect_hits) goto next_line; /* "grep -v -e foo -e bla" should list lines * that do not have either, so inversion should * be done outside. */ if (opt->invert) hit = !hit; if (opt->unmatch_name_only) { if (hit) return 0; goto next_line; } if (hit) { count++; if (opt->status_only) return 1; if (opt->name_only) { show_name(opt, gs->name); return 1; } if (opt->count) goto next_line; if (binary_match_only) { opt->output(opt, "Binary file ", 12); output_color(opt, gs->name, strlen(gs->name), opt->color_filename); opt->output(opt, " matches\n", 9); return 1; } /* Hit at this line. If we haven't shown the * pre-context lines, we would need to show them. */ if (opt->pre_context || opt->funcbody) show_pre_context(opt, gs, bol, eol, lno); else if (opt->funcname) show_funcname_line(opt, gs, bol, lno); show_line(opt, bol, eol, gs->name, lno, ':'); last_hit = lno; if (opt->funcbody) show_function = 1; goto next_line; } if (show_function && match_funcname(opt, gs, bol, eol)) show_function = 0; if (show_function || (last_hit && lno <= last_hit + opt->post_context)) { /* If the last hit is within the post context, * we need to show this line. */ show_line(opt, bol, eol, gs->name, lno, '-'); } next_line: bol = eol + 1; if (!left) break; left--; lno++; } if (collect_hits) return 0; if (opt->status_only) return 0; if (opt->unmatch_name_only) { /* We did not see any hit, so we want to show this */ show_name(opt, gs->name); return 1; } xdiff_clear_find_func(&xecfg); opt->priv = NULL; /* NEEDSWORK: * The real "grep -c foo *.c" gives many "bar.c:0" lines, * which feels mostly useless but sometimes useful. Maybe * make it another option? For now suppress them. */ if (opt->count && count) { char buf[32]; if (opt->pathname) { output_color(opt, gs->name, strlen(gs->name), opt->color_filename); output_sep(opt, ':'); } snprintf(buf, sizeof(buf), "%u\n", count); opt->output(opt, buf, strlen(buf)); return 1; } return !!last_hit; }
static int grep_buffer_1(struct grep_opt *opt, const char *name, char *buf, unsigned long size, int collect_hits) { char *bol = buf; unsigned long left = size; unsigned lno = 1; unsigned last_hit = 0; int binary_match_only = 0; unsigned count = 0; enum grep_context ctx = GREP_CONTEXT_HEAD; xdemitconf_t xecfg; opt->last_shown = 0; if (buffer_is_binary(buf, size)) { switch (opt->binary) { case GREP_BINARY_DEFAULT: binary_match_only = 1; break; case GREP_BINARY_NOMATCH: return 0; /* Assume unmatch */ break; default: break; } } memset(&xecfg, 0, sizeof(xecfg)); if (opt->funcname && !opt->unmatch_name_only && !opt->status_only && !opt->name_only && !binary_match_only && !collect_hits) { struct userdiff_driver *drv = userdiff_find_by_path(name); if (drv && drv->funcname.pattern) { const struct userdiff_funcname *pe = &drv->funcname; xdiff_set_find_func(&xecfg, pe->pattern, pe->cflags); opt->priv = &xecfg; } } while (left) { char *eol, ch; int hit; eol = end_of_line(bol, &left); ch = *eol; *eol = 0; if ((ctx == GREP_CONTEXT_HEAD) && (eol == bol)) ctx = GREP_CONTEXT_BODY; hit = match_line(opt, bol, eol, ctx, collect_hits); *eol = ch; if (collect_hits) goto next_line; /* "grep -v -e foo -e bla" should list lines * that do not have either, so inversion should * be done outside. */ if (opt->invert) hit = !hit; if (opt->unmatch_name_only) { if (hit) return 0; goto next_line; } if (hit) { count++; if (opt->status_only) return 1; if (binary_match_only) { printf("Binary file %s matches\n", name); return 1; } if (opt->name_only) { show_name(opt, name); return 1; } /* Hit at this line. If we haven't shown the * pre-context lines, we would need to show them. * When asked to do "count", this still show * the context which is nonsense, but the user * deserves to get that ;-). */ if (opt->pre_context) show_pre_context(opt, name, buf, bol, lno); else if (opt->funcname) show_funcname_line(opt, name, buf, bol, lno); if (!opt->count) show_line(opt, bol, eol, name, lno, ':'); last_hit = lno; } else if (last_hit && lno <= last_hit + opt->post_context) { /* If the last hit is within the post context, * we need to show this line. */ show_line(opt, bol, eol, name, lno, '-'); } next_line: bol = eol + 1; if (!left) break; left--; lno++; } if (collect_hits) return 0; if (opt->status_only) return 0; if (opt->unmatch_name_only) { /* We did not see any hit, so we want to show this */ show_name(opt, name); return 1; } xdiff_clear_find_func(&xecfg); opt->priv = NULL; /* NEEDSWORK: * The real "grep -c foo *.c" gives many "bar.c:0" lines, * which feels mostly useless but sometimes useful. Maybe * make it another option? For now suppress them. */ if (opt->count && count) printf("%s%c%u\n", name, opt->null_following_name ? '\0' : ':', count); return !!last_hit; }
static nx_logdata_t *xm_multiline_input_func(nx_module_input_t *input, void *data) { volatile int i; nx_logdata_t * volatile retval = NULL; boolean foundcr = FALSE; nx_xm_multiline_ctx_t *ctx; nx_xm_multiline_conf_t *modconf; nx_module_t *module; boolean appendline; boolean gotline; volatile boolean done = FALSE; ASSERT(input != NULL); ASSERT(input->buflen >= 0); ASSERT(data != NULL); if ( input->buflen == 0 ) { return ( NULL ); } if ( input->ctx == NULL ) { input->ctx = apr_pcalloc(input->pool, sizeof(nx_xm_multiline_ctx_t)); } ctx = input->ctx; module = (nx_module_t *) data; modconf = (nx_xm_multiline_conf_t *) module->config; do { foundcr = FALSE; appendline = TRUE; gotline = FALSE; for ( i = 0; (i < input->buflen) && (gotline == FALSE) ; i++ ) { switch ( input->buf[input->bufstart + i] ) { case APR_ASCII_CR: if ( foundcr == TRUE ) { gotline = TRUE; i--; } else { foundcr = TRUE; } break; case APR_ASCII_LF: if ( foundcr == TRUE ) { gotline = TRUE; i--; } else { foundcr = TRUE; } break; default: if ( foundcr == TRUE ) { gotline = TRUE; i--; } break; } } if ( ctx->tmpline == NULL ) { ctx->tmpline = nx_logdata_new_logline(input->buf + input->bufstart, i); } else { nx_logdata_append_logline(ctx->tmpline, input->buf + input->bufstart, i); } //log_info("tmpline: [%s]", ctx->tmpline->raw_event->buf); if ( foundcr == TRUE ) { // got a complete line if ( module->exec != NULL ) { nx_expr_eval_ctx_t eval_ctx; nx_exception_t e; nx_expr_eval_ctx_init(&eval_ctx, ctx->tmpline, module, input); try { nx_expr_statement_list_execute(&eval_ctx, module->exec); } catch(e) { log_exception(e); } if ( eval_ctx.logdata == NULL ) { // dropped //log_info("dropped"); appendline = FALSE; ctx->tmpline = NULL; } else { // TODO: merge fields } nx_expr_eval_ctx_destroy(&eval_ctx); } if ( appendline == TRUE ) { // not dropped size_t len; boolean gotheaderline = FALSE; boolean gotendline = FALSE; //log_info("appendline"); // ignore trailing new line for ( len = ctx->tmpline->raw_event->len; (len > 0) && ((ctx->tmpline->raw_event->buf[len - 1] == APR_ASCII_CR) || (ctx->tmpline->raw_event->buf[len - 1] == APR_ASCII_LF)); len--); // Check headerline if ( modconf->headerline != NULL ) { gotheaderline = match_line(modconf->headerline, ctx->tmpline->raw_event->buf, len); } // Check endline if ( modconf->endline != NULL ) { gotendline = match_line(modconf->endline, ctx->tmpline->raw_event->buf, len); } // log_debug("gotheader: %d gotend: %d for [%s]", gotheaderline, gotendline, // ctx->tmpline->raw_event->buf); if ( (gotendline == TRUE) && (gotheaderline == TRUE) ) { log_error("HeaderLine and Endline both match"); } //log_info("gotheaderline: %d string: [%s]", gotheaderline, ctx->tmpline->raw_event->buf); if ( ctx->logdata == NULL ) { if ( (modconf->fixedlinecount <= 0) && (gotheaderline == FALSE) ) { // return if no header is found and there is no fixed linecount //log_info("return logdata: no header, no fixed linecount"); retval = ctx->tmpline; ctx->tmpline = NULL; ctx->linecount = 0; done = TRUE; } else { ctx->logdata = ctx->tmpline; ctx->tmpline = NULL; (ctx->linecount)++; } } else { // there is saved data if ( gotendline == TRUE ) { nx_string_append(ctx->logdata->raw_event, ctx->tmpline->raw_event->buf, (int) ctx->tmpline->raw_event->len); nx_logdata_free(ctx->tmpline); ctx->tmpline = NULL; retval = ctx->logdata; ctx->logdata = NULL; done = TRUE; } else if ( gotheaderline == TRUE ) { //log_info("return logdata %lu: header ok", ctx->logdata); retval = ctx->logdata; ctx->logdata = ctx->tmpline; ctx->tmpline = NULL; (ctx->linecount)++; done = TRUE; } else { nx_string_append(ctx->logdata->raw_event, ctx->tmpline->raw_event->buf, (int) ctx->tmpline->raw_event->len); nx_logdata_free(ctx->tmpline); ctx->tmpline = NULL; (ctx->linecount)++; } } // Check FixedLineCount if ( modconf->fixedlinecount > 0 ) { if ( ctx->linecount >= modconf->fixedlinecount ) { //log_info("return logdata: fixed linecount"); retval = ctx->logdata; ctx->logdata = NULL; ctx->linecount = 0; done = TRUE; } } } } input->buflen -= i; input->bufstart += i; //log_info("buflen: %d, foundcr: %d, i: %d, linecount: %d", input->buflen, foundcr, i, ctx->linecount); if ( input->buflen <= 0 ) { done = TRUE; } } while ( done != TRUE ); if ( retval != NULL ) { nx_string_strip_crlf(retval->raw_event); } return ( retval ); }
static int translate_files(FILE *inFile, FILE *outFile) { char *Line = malloc(LINESIZE + 1); char *path = malloc(LINESIZE + 1); char *LineOut = malloc(LINESIZE + 1); int c; unsigned char ch; int i = 0; const char *pc = kdbg_cont; const char *p = kdbg_prompt; const char *p_eos = p + sizeof(KDBG_PROMPT) - 1; //end of string pos if (Line && path && LineOut) { memset(Line, '\0', LINESIZE + 1); if (opt_console) { while ((c = fgetc(inFile)) != EOF) { if (opt_quit)break; ch = (unsigned char)c; if (!opt_raw) { switch (ch) { case '\n': if ( strncmp(Line, KDBG_DISCARD, sizeof(KDBG_DISCARD)-1) == 0 ) { memset(Line, '\0', LINESIZE); // flushed } else { Line[1] = handle_escape_cmd(outFile, Line, path, LineOut); if (Line[1] != KDBG_ESC_CHAR) { if (p == p_eos) { // kdbg prompt, so already echoed char by char memset(Line, '\0', LINESIZE); translate_char(c, outFile); } else { if (match_line(outFile, Line)) { translate_line(outFile, Line, path, LineOut); translate_char(c, outFile); report(outFile); } } } } i = 0; p = kdbg_prompt; pc = kdbg_cont; break; case '<': i = 0; Line[i++] = ch; break; case '>': if (ch == *p) { p = p_eos; translate_line(outFile, Line, path, LineOut); } if (p != p_eos) { if (i < LINESIZE) { Line[i++] = ch; translate_line(outFile, Line, path, LineOut); } else { translate_line(outFile, Line, path, LineOut); translate_char(c, outFile); } } else translate_char(c, outFile); i = 0; break; default: if (ch == *p)p++; if (ch == *pc)pc++; if (i < LINESIZE) { Line[i++] = ch; if (p == p_eos) { translate_char(c, outFile); } else if (!*pc) { translate_line(outFile, Line, path, LineOut); i = 0; } } else { translate_line(outFile, Line, path, LineOut); translate_char(c, outFile); i = 0; } } } else translate_char(c, outFile); } } else { // Line by line, slightly faster but less interactive while (fgets(Line, LINESIZE, inFile) != NULL) { if (opt_quit)break; if (!opt_raw) { translate_line(outFile, Line, path, LineOut); report(outFile); } else log(outFile, "%s", Line); } } } if (opt_Revision && (strstr(opt_Revision, "regscan") == opt_Revision)) { char *s = strchr(opt_Revision, ','); if (s) { *s++ = '\0'; revinfo.range = atoi(s); } regscan(outFile); } if (opt_stats) { stat_print(outFile, &summ); if (logFile) stat_print(logFile, &summ); } free(LineOut); free(Line); free(path); return 0; }
static int grep_buffer_1(struct grep_opt *opt, const char *name, char *buf, unsigned long size, int collect_hits) { char *bol = buf; unsigned long left = size; unsigned lno = 1; struct pre_context_line { char *bol; char *eol; } *prev = NULL, *pcl; unsigned last_hit = 0; unsigned last_shown = 0; int binary_match_only = 0; const char *hunk_mark = ""; unsigned count = 0; enum grep_context ctx = GREP_CONTEXT_HEAD; if (buffer_is_binary(buf, size)) { switch (opt->binary) { case GREP_BINARY_DEFAULT: binary_match_only = 1; break; case GREP_BINARY_NOMATCH: return 0; /* Assume unmatch */ break; default: break; } } if (opt->pre_context) prev = xcalloc(opt->pre_context, sizeof(*prev)); if (opt->pre_context || opt->post_context) hunk_mark = "--\n"; while (left) { char *eol, ch; int hit; eol = end_of_line(bol, &left); ch = *eol; *eol = 0; if ((ctx == GREP_CONTEXT_HEAD) && (eol == bol)) ctx = GREP_CONTEXT_BODY; hit = match_line(opt, bol, eol, ctx, collect_hits); *eol = ch; if (collect_hits) goto next_line; /* "grep -v -e foo -e bla" should list lines * that do not have either, so inversion should * be done outside. */ if (opt->invert) hit = !hit; if (opt->unmatch_name_only) { if (hit) return 0; goto next_line; } if (hit) { count++; if (opt->status_only) return 1; if (binary_match_only) { printf("Binary file %s matches\n", name); return 1; } if (opt->name_only) { show_name(opt, name); return 1; } /* Hit at this line. If we haven't shown the * pre-context lines, we would need to show them. * When asked to do "count", this still show * the context which is nonsense, but the user * deserves to get that ;-). */ if (opt->pre_context) { unsigned from; if (opt->pre_context < lno) from = lno - opt->pre_context; else from = 1; if (from <= last_shown) from = last_shown + 1; if (last_shown && from != last_shown + 1) printf(hunk_mark); while (from < lno) { pcl = &prev[lno-from-1]; show_line(opt, pcl->bol, pcl->eol, name, from, '-'); from++; } last_shown = lno-1; } if (last_shown && lno != last_shown + 1) printf(hunk_mark); if (!opt->count) show_line(opt, bol, eol, name, lno, ':'); last_shown = last_hit = lno; } else if (last_hit && lno <= last_hit + opt->post_context) { /* If the last hit is within the post context, * we need to show this line. */ if (last_shown && lno != last_shown + 1) printf(hunk_mark); show_line(opt, bol, eol, name, lno, '-'); last_shown = lno; } if (opt->pre_context) { memmove(prev+1, prev, (opt->pre_context-1) * sizeof(*prev)); prev->bol = bol; prev->eol = eol; } next_line: bol = eol + 1; if (!left) break; left--; lno++; } free(prev); if (collect_hits) return 0; if (opt->status_only) return 0; if (opt->unmatch_name_only) { /* We did not see any hit, so we want to show this */ show_name(opt, name); return 1; } /* NEEDSWORK: * The real "grep -c foo *.c" gives many "bar.c:0" lines, * which feels mostly useless but sometimes useful. Maybe * make it another option? For now suppress them. */ if (opt->count && count) printf("%s%c%u\n", name, opt->null_following_name ? '\0' : ':', count); return !!last_hit; }