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