annotate rcg.c @ 9:a367f80b847b

add color and bold options
author paulo@hit-nxdomain.opendns.com
date Fri, 07 May 2010 01:02:18 -0700
parents 5ab8d6c1a37c
children 4ef47c3bdce6
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@9 15 const char *_CLR_START = "\x1B[";
paulo@9 16 const char *_CLR_BOLD = "1;";
paulo@9 17 char *CLR_START;
paulo@5 18 const char *CLR_END = "m";
paulo@5 19 const char *CLR_CLEAR = "\x1B[0m";
pang@1 20
paulo@9 21 char *CLR_CLR;
paulo@9 22
paulo@9 23 const char *CLR_FG_RED = "31";
paulo@9 24
paulo@9 25 typedef struct _colors {
paulo@9 26 char *name;
paulo@9 27 char *fg;
paulo@9 28 char *bg;
paulo@9 29 } Colors;
paulo@9 30
paulo@9 31 const Colors COLORS[] = {
paulo@9 32 { "black", "30", "40" },
paulo@9 33 { "red", "31", "41" },
paulo@9 34 { "green", "32", "42" },
paulo@9 35 { "brown", "33", "43" },
paulo@9 36 { "blue", "34", "44" },
paulo@9 37 { "magenta", "35", "45" },
paulo@9 38 { "cyan", "36", "46" },
paulo@9 39 { "white", "37", "47" },
paulo@9 40 { "default", "39", "49" },
paulo@9 41 { NULL },
paulo@9 42 };
paulo@9 43
paulo@9 44 char *getFGColor(char *cname)
paulo@9 45 {
paulo@9 46 Colors *c;
paulo@9 47 for (c = COLORS; c->name; c++)
paulo@9 48 {
paulo@9 49 if (strncmp(cname, c->name, strlen(c->name)) == 0)
paulo@9 50 return c->fg;
paulo@9 51 }
paulo@9 52 return NULL;
paulo@9 53 }
paulo@9 54
paulo@9 55 char *getBGColor(char *cname)
paulo@9 56 {
paulo@9 57 Colors *c;
paulo@9 58 for (c = COLORS; c->name; c++)
paulo@9 59 {
paulo@9 60 if (strncmp(cname, c->name, strlen(c->name)) == 0)
paulo@9 61 return c->bg;
paulo@9 62 }
paulo@9 63 return NULL;
paulo@9 64 }
paulo@9 65
paulo@8 66 int colorLine = 0;
paulo@9 67 int embolden = 0;
paulo@9 68 char *g_fg = "red";
paulo@9 69 char *g_bg = "";
paulo@8 70
paulo@4 71 typedef enum _exit_code {
paulo@4 72 EXIT_OK,
paulo@4 73 EXIT_REALLOC_ERROR,
paulo@4 74 EXIT_ARGS_ERROR,
paulo@4 75 } Exit_code;
paulo@4 76
paulo@3 77 int re_error(int errcode, const regex_t *re)
paulo@3 78 {
paulo@3 79 char *err_string = calloc(BUFSIZE, sizeof(char));
paulo@3 80 regerror(errcode, re, err_string, BUFSIZE*sizeof(char));
paulo@3 81 fprintf(stderr, "%s \n", err_string);
paulo@3 82 free(err_string);
paulo@3 83 return errcode;
paulo@3 84 }
paulo@3 85
paulo@4 86 Exit_code realloc_error()
paulo@3 87 {
paulo@3 88 fprintf(stderr, "realloc() failure \n");
paulo@4 89 return EXIT_REALLOC_ERROR;
paulo@4 90 }
paulo@4 91
paulo@4 92 Exit_code args_error()
paulo@4 93 {
paulo@4 94 fprintf(stderr, "Invalid or nonexistent argument. \n");
paulo@4 95 return EXIT_ARGS_ERROR;
paulo@4 96 }
paulo@4 97
paulo@4 98 // returns regular expression argument
paulo@4 99 char *parseArgs(int argc, char **argv)
paulo@4 100 {
paulo@4 101 static struct option long_options[] =
paulo@4 102 {
paulo@8 103 { "line", 0, 0, 'l' },
paulo@9 104 { "bold", 0, 0, 'B' },
paulo@4 105 { 0, 0, 0, 0 },
paulo@4 106 };
paulo@4 107
paulo@4 108 int c;
paulo@4 109 int l;
paulo@9 110 while ((c = getopt_long(argc, argv, "lBf:b:", long_options, &l)) >= 0)
paulo@4 111 {
paulo@8 112 if (c == 'l')
paulo@8 113 colorLine = 1;
paulo@9 114 else if (c == 'B')
paulo@9 115 embolden = 1;
paulo@9 116 else if (c == 'f')
paulo@9 117 g_fg = strdup(optarg);
paulo@9 118 else if (c == 'b')
paulo@9 119 g_bg = strdup(optarg);
paulo@4 120 }
paulo@4 121
paulo@4 122 if (optind >= argc)
paulo@4 123 exit(args_error());
paulo@4 124
paulo@4 125 return argv[optind];
paulo@3 126 }
paulo@3 127
pang@1 128 int main(int argc, char **argv)
pang@1 129 {
paulo@4 130 char *re_expression = parseArgs(argc, argv);
paulo@4 131
paulo@5 132 //fprintf(stderr, "re_expression = %s \n", re_expression); //d/ 20100405 PBA
paulo@4 133
pang@1 134 char *buf = calloc(BUFSIZE, sizeof(char));
pang@1 135
paulo@3 136 int re_err;
pang@1 137 regex_t *re = calloc(1, sizeof(regex_t));
paulo@4 138 re_err = regcomp(re, re_expression, REG_EXTENDED);
paulo@3 139 if (re_err != 0)
paulo@3 140 exit(re_error(re_err, re));
pang@1 141
pang@2 142 regmatch_t *rem = calloc(1, sizeof(regmatch_t));
pang@1 143
paulo@9 144 if (embolden)
paulo@9 145 {
paulo@9 146 CLR_START = calloc(strlen(_CLR_START) + strlen(_CLR_BOLD) + 1, sizeof(char));
paulo@9 147 strcpy(CLR_START, _CLR_START);
paulo@9 148 strcat(CLR_START, _CLR_BOLD);
paulo@9 149 }
paulo@9 150 else
paulo@9 151 CLR_START = strdup(_CLR_START);
paulo@9 152
paulo@9 153 CLR_CLR = getFGColor(g_fg);
paulo@9 154 if (!CLR_CLR)
paulo@9 155 exit(args_error());
paulo@9 156 if (strlen(g_bg) > 0)
paulo@9 157 {
paulo@9 158 char *fgcolor = getFGColor(g_fg);
paulo@9 159 char *bgcolor = getBGColor(g_bg);
paulo@9 160 if (bgcolor)
paulo@9 161 {
paulo@9 162 size_t l = strlen(fgcolor) + 1 + strlen(bgcolor);
paulo@9 163 CLR_CLR = calloc((l + 1), sizeof(char));
paulo@9 164 if (!CLR_CLR)
paulo@9 165 exit(realloc_error());
paulo@9 166 strcpy(CLR_CLR, fgcolor);
paulo@9 167 strcat(CLR_CLR, ";");
paulo@9 168 strcat(CLR_CLR, bgcolor);
paulo@9 169 }
paulo@9 170 else
paulo@9 171 exit(args_error());
paulo@9 172 }
paulo@9 173
pang@1 174 size_t CLR_START_len = strlen(CLR_START);
paulo@9 175 size_t CLR_CLR_len = strlen(CLR_CLR);
pang@1 176 size_t CLR_END_len = strlen(CLR_END);
paulo@5 177 size_t CLR_CLEAR_len = strlen(CLR_CLEAR);
pang@1 178
paulo@7 179 char *out = NULL;
paulo@7 180
pang@1 181 while (fgets(buf, BUFSIZE, stdin))
pang@1 182 {
pang@2 183 int so = -1;
pang@2 184 int eo = -1;
pang@1 185
paulo@6 186 size_t out_len = strlen(buf) + 1;
paulo@3 187 unsigned int out_pos = 0;
paulo@3 188 unsigned int buf_pos = 0;
paulo@3 189
paulo@4 190 for (re_err = 0; re_err != REG_NOMATCH;)
pang@2 191 {
paulo@3 192 re_err = regexec(re, &buf[buf_pos], 1, rem, 0);
pang@1 193
paulo@3 194 //fprintf(stderr, "%s", &buf[buf_pos]); //d// 20100405 PBA
paulo@3 195
pang@2 196 if (out_len >= (BUFSIZE - buf_pos))
pang@2 197 out_len = (BUFSIZE - buf_pos) - 1;
pang@1 198
paulo@9 199 out = realloc(out, out_len*sizeof(char));
paulo@7 200 if (!out)
paulo@7 201 exit(realloc_error());
paulo@7 202
paulo@8 203 if (colorLine)
paulo@8 204 {
paulo@8 205 so = 0;
paulo@8 206 eo = out_len - 1;
paulo@8 207 }
paulo@8 208 else
paulo@8 209 {
paulo@8 210 so = rem[0].rm_so;
paulo@8 211 eo = rem[0].rm_eo;
paulo@8 212 }
paulo@8 213
paulo@7 214 int match_len = eo - so;
pang@1 215
paulo@3 216 //fprintf(stderr, "%d %d \n", so, eo); //d// 20100327 PBA
pang@1 217
paulo@7 218 if (re_err != REG_NOMATCH && so >= 0 && eo >= 0 && match_len > 0)
pang@1 219 {
paulo@9 220 out_len += CLR_START_len + CLR_CLR_len + CLR_END_len + CLR_CLEAR_len;
paulo@9 221 out = realloc(out, out_len*sizeof(char));
paulo@3 222 if (!out)
paulo@3 223 exit(realloc_error());
paulo@3 224 strncpy(&out[out_pos], &buf[buf_pos], so);
paulo@3 225 out_pos += so;
paulo@3 226 buf_pos += so;
pang@1 227 strncpy(&out[out_pos], CLR_START, CLR_START_len);
pang@1 228 out_pos += CLR_START_len;
paulo@9 229 strncpy(&out[out_pos], CLR_CLR, CLR_CLR_len);
paulo@9 230 out_pos += CLR_CLR_len;
paulo@5 231 strncpy(&out[out_pos], CLR_END, CLR_END_len);
paulo@5 232 out_pos += CLR_END_len;
pang@2 233 strncpy(&out[out_pos], &buf[buf_pos], match_len);
pang@1 234 out_pos += match_len;
paulo@5 235 strncpy(&out[out_pos], CLR_CLEAR, CLR_CLEAR_len);
paulo@5 236 out_pos += CLR_CLEAR_len;
pang@2 237
pang@2 238 buf_pos += match_len;
pang@1 239 }
pang@2 240 else
paulo@5 241 {
paulo@3 242 strncpy(&out[out_pos], &buf[buf_pos], out_len - out_pos);
paulo@7 243 out[out_len - 1] = '\0';
paulo@5 244 }
pang@1 245 }
pang@1 246
pang@1 247 fputs(out, stdout);
pang@1 248 }
pang@1 249
paulo@4 250 return EXIT_OK;
pang@1 251 }