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 }
|