annotate rcg.c @ 8:5ab8d6c1a37c

add line coloring option
author paulo@hit-nxdomain.opendns.com
date Thu, 06 May 2010 23:21:30 -0700
parents 0b9cf47655fe
children a367f80b847b
rev   line source
pang@1 1 #include <stdio.h>
pang@1 2 #include <stdlib.h>
pang@1 3 #include <regex.h>
pang@1 4
pang@1 5 #define __USE_GNU
pang@1 6 #include <string.h>
pang@1 7
paulo@4 8 #include <unistd.h>
paulo@4 9
paulo@4 10 #define _GNU_SOURCE
paulo@4 11 #include <getopt.h>
paulo@4 12
pang@1 13 const size_t BUFSIZE = 5000;
pang@1 14
paulo@5 15 const char *CLR_START = "\x1B[31";
paulo@5 16 const char *CLR_END = "m";
paulo@5 17 const char *CLR_CLEAR = "\x1B[0m";
pang@1 18
paulo@8 19 int colorLine = 0;
paulo@8 20
paulo@4 21 typedef enum _exit_code {
paulo@4 22 EXIT_OK,
paulo@4 23 EXIT_REALLOC_ERROR,
paulo@4 24 EXIT_ARGS_ERROR,
paulo@4 25 } Exit_code;
paulo@4 26
paulo@3 27 int re_error(int errcode, const regex_t *re)
paulo@3 28 {
paulo@3 29 char *err_string = calloc(BUFSIZE, sizeof(char));
paulo@3 30 regerror(errcode, re, err_string, BUFSIZE*sizeof(char));
paulo@3 31 fprintf(stderr, "%s \n", err_string);
paulo@3 32 free(err_string);
paulo@3 33 return errcode;
paulo@3 34 }
paulo@3 35
paulo@4 36 Exit_code realloc_error()
paulo@3 37 {
paulo@3 38 fprintf(stderr, "realloc() failure \n");
paulo@4 39 return EXIT_REALLOC_ERROR;
paulo@4 40 }
paulo@4 41
paulo@4 42 Exit_code args_error()
paulo@4 43 {
paulo@4 44 fprintf(stderr, "Invalid or nonexistent argument. \n");
paulo@4 45 return EXIT_ARGS_ERROR;
paulo@4 46 }
paulo@4 47
paulo@4 48 // returns regular expression argument
paulo@4 49 char *parseArgs(int argc, char **argv)
paulo@4 50 {
paulo@4 51 static struct option long_options[] =
paulo@4 52 {
paulo@8 53 { "line", 0, 0, 'l' },
paulo@4 54 { 0, 0, 0, 0 },
paulo@4 55 };
paulo@4 56
paulo@4 57 int c;
paulo@4 58 int l;
paulo@8 59 while ((c = getopt_long(argc, argv, "l", long_options, &l)) >= 0)
paulo@4 60 {
paulo@8 61 if (c == 'l')
paulo@8 62 colorLine = 1;
paulo@4 63 }
paulo@4 64
paulo@4 65 if (optind >= argc)
paulo@4 66 exit(args_error());
paulo@4 67
paulo@4 68 return argv[optind];
paulo@3 69 }
paulo@3 70
pang@1 71 int main(int argc, char **argv)
pang@1 72 {
paulo@4 73 char *re_expression = parseArgs(argc, argv);
paulo@4 74
paulo@5 75 //fprintf(stderr, "re_expression = %s \n", re_expression); //d/ 20100405 PBA
paulo@4 76
pang@1 77 char *buf = calloc(BUFSIZE, sizeof(char));
pang@1 78
paulo@3 79 int re_err;
pang@1 80 regex_t *re = calloc(1, sizeof(regex_t));
paulo@4 81 re_err = regcomp(re, re_expression, REG_EXTENDED);
paulo@3 82 if (re_err != 0)
paulo@3 83 exit(re_error(re_err, re));
pang@1 84
pang@2 85 regmatch_t *rem = calloc(1, sizeof(regmatch_t));
pang@1 86
pang@1 87 size_t CLR_START_len = strlen(CLR_START);
pang@1 88 size_t CLR_END_len = strlen(CLR_END);
paulo@5 89 size_t CLR_CLEAR_len = strlen(CLR_CLEAR);
pang@1 90
paulo@7 91 char *out = NULL;
paulo@7 92
pang@1 93 while (fgets(buf, BUFSIZE, stdin))
pang@1 94 {
pang@2 95 int so = -1;
pang@2 96 int eo = -1;
pang@1 97
paulo@6 98 size_t out_len = strlen(buf) + 1;
paulo@3 99 unsigned int out_pos = 0;
paulo@3 100 unsigned int buf_pos = 0;
paulo@3 101
paulo@4 102 for (re_err = 0; re_err != REG_NOMATCH;)
pang@2 103 {
paulo@3 104 re_err = regexec(re, &buf[buf_pos], 1, rem, 0);
pang@1 105
paulo@3 106 //fprintf(stderr, "%s", &buf[buf_pos]); //d// 20100405 PBA
paulo@3 107
pang@2 108 if (out_len >= (BUFSIZE - buf_pos))
pang@2 109 out_len = (BUFSIZE - buf_pos) - 1;
pang@1 110
paulo@7 111 out = (char *)realloc(out, out_len*sizeof(char));
paulo@7 112 if (!out)
paulo@7 113 exit(realloc_error());
paulo@7 114
paulo@8 115 if (colorLine)
paulo@8 116 {
paulo@8 117 so = 0;
paulo@8 118 eo = out_len - 1;
paulo@8 119 }
paulo@8 120 else
paulo@8 121 {
paulo@8 122 so = rem[0].rm_so;
paulo@8 123 eo = rem[0].rm_eo;
paulo@8 124 }
paulo@8 125
paulo@7 126 int match_len = eo - so;
pang@1 127
paulo@3 128 //fprintf(stderr, "%d %d \n", so, eo); //d// 20100327 PBA
pang@1 129
paulo@7 130 if (re_err != REG_NOMATCH && so >= 0 && eo >= 0 && match_len > 0)
pang@1 131 {
paulo@5 132 out_len += CLR_START_len + CLR_END_len + CLR_CLEAR_len;
pang@1 133 out = (char *)realloc(out, out_len*sizeof(char));
paulo@3 134 if (!out)
paulo@3 135 exit(realloc_error());
paulo@3 136 strncpy(&out[out_pos], &buf[buf_pos], so);
paulo@3 137 out_pos += so;
paulo@3 138 buf_pos += so;
pang@1 139 strncpy(&out[out_pos], CLR_START, CLR_START_len);
pang@1 140 out_pos += CLR_START_len;
paulo@5 141 strncpy(&out[out_pos], CLR_END, CLR_END_len);
paulo@5 142 out_pos += CLR_END_len;
pang@2 143 strncpy(&out[out_pos], &buf[buf_pos], match_len);
pang@1 144 out_pos += match_len;
paulo@5 145 strncpy(&out[out_pos], CLR_CLEAR, CLR_CLEAR_len);
paulo@5 146 out_pos += CLR_CLEAR_len;
pang@2 147
pang@2 148 buf_pos += match_len;
pang@1 149 }
pang@2 150 else
paulo@5 151 {
paulo@3 152 strncpy(&out[out_pos], &buf[buf_pos], out_len - out_pos);
paulo@7 153 out[out_len - 1] = '\0';
paulo@5 154 }
pang@1 155 }
pang@1 156
pang@1 157 fputs(out, stdout);
pang@1 158 }
pang@1 159
paulo@4 160 return EXIT_OK;
pang@1 161 }