view rcg.c @ 14:669266246c6b

rcg.c: simplify string concatenation
author paulo@thepaulopc
date Fri, 12 Nov 2010 00:08:34 -0800
parents 2fb87616ab65
children acf12a2e872d
line source
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <regex.h>
5 #include <string.h>
7 #include <unistd.h>
9 #define _GNU_SOURCE
10 #include <getopt.h>
12 const size_t BUFSIZE = 5000;
14 const char *_CLR_START = "\x1B[";
15 const char *_CLR_BOLD = "1;";
16 char *CLR_START;
17 const char *CLR_END = "m";
18 const char *CLR_CLEAR = "\x1B[0m";
20 typedef struct _colors {
21 char *name;
22 char *fg;
23 char *bg;
24 } Colors;
26 const Colors COLORS[] = {
27 { "black", "30", "40" },
28 { "red", "31", "41" },
29 { "green", "32", "42" },
30 { "brown", "33", "43" },
31 { "blue", "34", "44" },
32 { "magenta", "35", "45" },
33 { "cyan", "36", "46" },
34 { "white", "37", "47" },
35 { "default", "39", "49" },
36 { NULL },
37 };
39 char *getFGColor(char *cname)
40 {
41 Colors *c;
42 for (c = COLORS; c->name; c++)
43 {
44 if (strncmp(cname, c->name, strlen(c->name)) == 0)
45 return c->fg;
46 }
47 return NULL;
48 }
50 char *getBGColor(char *cname)
51 {
52 Colors *c;
53 for (c = COLORS; c->name; c++)
54 {
55 if (strncmp(cname, c->name, strlen(c->name)) == 0)
56 return c->bg;
57 }
58 return NULL;
59 }
61 int colorLine = 0;
62 int embolden = 0;
63 char *g_fg = "";
64 char *g_bg = "";
66 typedef enum _exit_code {
67 EXIT_OK,
68 EXIT_REALLOC_ERROR,
69 EXIT_ARGS_ERROR,
70 } Exit_code;
72 int re_error(int errcode, const regex_t *re)
73 {
74 char *err_string = calloc(BUFSIZE, sizeof(char));
75 regerror(errcode, re, err_string, BUFSIZE*sizeof(char));
76 fprintf(stderr, "%s \n", err_string);
77 free(err_string);
78 return errcode;
79 }
81 Exit_code realloc_error()
82 {
83 fprintf(stderr, "realloc() failure \n");
84 return EXIT_REALLOC_ERROR;
85 }
87 Exit_code args_error()
88 {
89 fprintf(stderr, "Invalid or nonexistent argument. \n");
90 return EXIT_ARGS_ERROR;
91 }
93 // returns regular expression argument
94 char *parseArgs(int argc, char **argv)
95 {
96 static struct option long_options[] =
97 {
98 { "line", 0, 0, 'l' },
99 { "bold", 0, 0, 'B' },
100 { 0, 0, 0, 0 },
101 };
103 int c;
104 int l;
105 while ((c = getopt_long(argc, argv, "lBf:b:", long_options, &l)) >= 0)
106 {
107 if (c == 'l')
108 colorLine = 1;
109 else if (c == 'B')
110 embolden = 1;
111 else if (c == 'f')
112 g_fg = strdup(optarg);
113 else if (c == 'b')
114 g_bg = strdup(optarg);
115 }
117 if (optind >= argc)
118 exit(args_error());
120 return argv[optind];
121 }
123 int main(int argc, char **argv)
124 {
125 char *re_expression = parseArgs(argc, argv);
127 //fprintf(stderr, "re_expression = %s \n", re_expression); //d/ 20100405 PBA
129 char *buf = calloc(BUFSIZE, sizeof(char));
131 int re_err;
132 regex_t *re = calloc(1, sizeof(regex_t));
133 re_err = regcomp(re, re_expression, REG_EXTENDED | REG_NEWLINE);
134 if (re_err != 0)
135 exit(re_error(re_err, re));
137 regmatch_t *rem = calloc(1, sizeof(regmatch_t));
139 if (embolden)
140 {
141 CLR_START = calloc(strlen(_CLR_START) + strlen(_CLR_BOLD) + 1, sizeof(char));
142 strcpy(CLR_START, _CLR_START);
143 strcat(CLR_START, _CLR_BOLD);
144 }
145 else
146 CLR_START = strdup(_CLR_START);
148 if (strlen(g_fg) == 0 && strlen(g_bg) == 0)
149 g_fg = "red";
150 else if (strlen(g_fg) == 0 && strlen(g_bg) > 0)
151 g_fg = "default";
153 char *fgcolor = getFGColor(g_fg);
154 if (!fgcolor)
155 exit(args_error());
157 char *clr = strdup(fgcolor);
158 if (strlen(g_bg) > 0)
159 {
160 char *bgcolor = getBGColor(g_bg);
161 if (bgcolor)
162 {
163 size_t l = strlen(clr) + 1 + strlen(bgcolor);
164 clr = realloc(clr, (l + 1)*sizeof(char));
165 if (!clr)
166 exit(realloc_error());
167 strcat(clr, ";");
168 strcat(clr, bgcolor);
169 }
170 else
171 exit(args_error());
172 }
174 char *out = NULL;
176 while (fgets(buf, BUFSIZE, stdin))
177 {
178 int so = -1;
179 int eo = -1;
181 size_t out_len = strlen(buf) + 1;
182 unsigned int out_pos = 0;
183 unsigned int buf_pos = 0;
185 for (re_err = 0; re_err != REG_NOMATCH;)
186 {
187 re_err = regexec(re, &buf[buf_pos], 1, rem, 0);
189 //fprintf(stderr, "%s", &buf[buf_pos]); //d// 20100405 PBA
191 if (out_len >= (BUFSIZE - buf_pos))
192 out_len = (BUFSIZE - buf_pos) - 1;
194 out = realloc(out, out_len*sizeof(char));
195 if (!out)
196 exit(realloc_error());
198 so = rem[0].rm_so;
199 eo = rem[0].rm_eo;
201 int match_len = eo - so;
203 if (colorLine && match_len > 0)
204 {
205 so = 0;
206 eo = out_len - 2;
207 match_len = eo - so;
208 }
210 //fprintf(stderr, "%d %d \n", so, eo); //d// 20100327 PBA
212 if (re_err != REG_NOMATCH && so >= 0 && eo >= 0 && match_len > 0)
213 {
214 size_t CLR_STRING_len = strlen(CLR_START) + strlen(clr) + strlen(CLR_END) + strlen(CLR_CLEAR);
216 out_len += CLR_STRING_len;
217 out = realloc(out, out_len*sizeof(char));
218 if (!out)
219 exit(realloc_error());
221 sprintf(&out[out_pos], "%.*s%s%s%s%.*s%s", so, &buf[buf_pos], CLR_START, clr, CLR_END, match_len, &buf[buf_pos + so], CLR_CLEAR);
223 buf_pos += match_len + so;
224 out_pos += CLR_STRING_len + match_len + so;
225 }
226 else
227 {
228 strncpy(&out[out_pos], &buf[buf_pos], out_len - out_pos);
229 out[out_len - 1] = '\0';
230 re_err = REG_NOMATCH;
231 }
232 }
234 fputs(out, stdout);
235 fflush(stdout);
236 }
238 return EXIT_OK;
239 }