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@4
|
19 typedef enum _exit_code {
|
paulo@4
|
20 EXIT_OK,
|
paulo@4
|
21 EXIT_REALLOC_ERROR,
|
paulo@4
|
22 EXIT_ARGS_ERROR,
|
paulo@4
|
23 } Exit_code;
|
paulo@4
|
24
|
paulo@3
|
25 int re_error(int errcode, const regex_t *re)
|
paulo@3
|
26 {
|
paulo@3
|
27 char *err_string = calloc(BUFSIZE, sizeof(char));
|
paulo@3
|
28 regerror(errcode, re, err_string, BUFSIZE*sizeof(char));
|
paulo@3
|
29 fprintf(stderr, "%s \n", err_string);
|
paulo@3
|
30 free(err_string);
|
paulo@3
|
31 return errcode;
|
paulo@3
|
32 }
|
paulo@3
|
33
|
paulo@4
|
34 Exit_code realloc_error()
|
paulo@3
|
35 {
|
paulo@3
|
36 fprintf(stderr, "realloc() failure \n");
|
paulo@4
|
37 return EXIT_REALLOC_ERROR;
|
paulo@4
|
38 }
|
paulo@4
|
39
|
paulo@4
|
40 Exit_code args_error()
|
paulo@4
|
41 {
|
paulo@4
|
42 fprintf(stderr, "Invalid or nonexistent argument. \n");
|
paulo@4
|
43 return EXIT_ARGS_ERROR;
|
paulo@4
|
44 }
|
paulo@4
|
45
|
paulo@4
|
46 // returns regular expression argument
|
paulo@4
|
47 char *parseArgs(int argc, char **argv)
|
paulo@4
|
48 {
|
paulo@4
|
49 static struct option long_options[] =
|
paulo@4
|
50 {
|
paulo@4
|
51 { 0, 0, 0, 0 },
|
paulo@4
|
52 };
|
paulo@4
|
53
|
paulo@4
|
54 int c;
|
paulo@4
|
55 int l;
|
paulo@4
|
56 while ((c = getopt_long(argc, argv, "", long_options, &l)) >= 0)
|
paulo@4
|
57 {
|
paulo@4
|
58 }
|
paulo@4
|
59
|
paulo@4
|
60 if (optind >= argc)
|
paulo@4
|
61 exit(args_error());
|
paulo@4
|
62
|
paulo@4
|
63 return argv[optind];
|
paulo@3
|
64 }
|
paulo@3
|
65
|
pang@1
|
66 int main(int argc, char **argv)
|
pang@1
|
67 {
|
paulo@4
|
68 char *re_expression = parseArgs(argc, argv);
|
paulo@4
|
69
|
paulo@5
|
70 //fprintf(stderr, "re_expression = %s \n", re_expression); //d/ 20100405 PBA
|
paulo@4
|
71
|
pang@1
|
72 char *buf = calloc(BUFSIZE, sizeof(char));
|
pang@1
|
73
|
paulo@3
|
74 int re_err;
|
pang@1
|
75 regex_t *re = calloc(1, sizeof(regex_t));
|
paulo@4
|
76 re_err = regcomp(re, re_expression, REG_EXTENDED);
|
paulo@3
|
77 if (re_err != 0)
|
paulo@3
|
78 exit(re_error(re_err, re));
|
pang@1
|
79
|
pang@2
|
80 regmatch_t *rem = calloc(1, sizeof(regmatch_t));
|
pang@1
|
81
|
pang@1
|
82 size_t CLR_START_len = strlen(CLR_START);
|
pang@1
|
83 size_t CLR_END_len = strlen(CLR_END);
|
paulo@5
|
84 size_t CLR_CLEAR_len = strlen(CLR_CLEAR);
|
pang@1
|
85
|
pang@1
|
86 while (fgets(buf, BUFSIZE, stdin))
|
pang@1
|
87 {
|
pang@2
|
88 int so = -1;
|
pang@2
|
89 int eo = -1;
|
pang@1
|
90
|
paulo@3
|
91 size_t out_len = strlen(buf);
|
paulo@3
|
92 char *out = calloc(out_len, sizeof(char));
|
paulo@3
|
93 unsigned int out_pos = 0;
|
paulo@3
|
94 unsigned int buf_pos = 0;
|
paulo@3
|
95
|
paulo@4
|
96 for (re_err = 0; re_err != REG_NOMATCH;)
|
pang@2
|
97 {
|
paulo@3
|
98 re_err = regexec(re, &buf[buf_pos], 1, rem, 0);
|
pang@1
|
99
|
paulo@3
|
100 //fprintf(stderr, "%s", &buf[buf_pos]); //d// 20100405 PBA
|
paulo@3
|
101
|
pang@2
|
102 if (out_len >= (BUFSIZE - buf_pos))
|
pang@2
|
103 out_len = (BUFSIZE - buf_pos) - 1;
|
pang@1
|
104
|
pang@2
|
105 so = rem[0].rm_so;
|
pang@2
|
106 eo = rem[0].rm_eo;
|
pang@1
|
107
|
paulo@3
|
108 //fprintf(stderr, "%d %d \n", so, eo); //d// 20100327 PBA
|
pang@1
|
109
|
paulo@3
|
110 if (re_err != REG_NOMATCH && so >= 0 && eo >= 0)
|
pang@1
|
111 {
|
pang@1
|
112 int match_len = eo - so;
|
paulo@5
|
113 out_len += CLR_START_len + CLR_END_len + CLR_CLEAR_len;
|
pang@1
|
114 out = (char *)realloc(out, out_len*sizeof(char));
|
paulo@3
|
115 if (!out)
|
paulo@3
|
116 exit(realloc_error());
|
paulo@3
|
117 strncpy(&out[out_pos], &buf[buf_pos], so);
|
paulo@3
|
118 out_pos += so;
|
paulo@3
|
119 buf_pos += so;
|
pang@1
|
120 strncpy(&out[out_pos], CLR_START, CLR_START_len);
|
pang@1
|
121 out_pos += CLR_START_len;
|
paulo@5
|
122 strncpy(&out[out_pos], CLR_END, CLR_END_len);
|
paulo@5
|
123 out_pos += CLR_END_len;
|
pang@2
|
124 strncpy(&out[out_pos], &buf[buf_pos], match_len);
|
pang@1
|
125 out_pos += match_len;
|
paulo@5
|
126 strncpy(&out[out_pos], CLR_CLEAR, CLR_CLEAR_len);
|
paulo@5
|
127 out_pos += CLR_CLEAR_len;
|
pang@2
|
128
|
pang@2
|
129 buf_pos += match_len;
|
pang@1
|
130 }
|
pang@2
|
131 else
|
paulo@5
|
132 {
|
paulo@3
|
133 strncpy(&out[out_pos], &buf[buf_pos], out_len - out_pos);
|
paulo@5
|
134 out[out_len] = '\0';
|
paulo@5
|
135 }
|
pang@1
|
136 }
|
pang@1
|
137
|
pang@1
|
138 fputs(out, stdout);
|
paulo@3
|
139 free(out);
|
pang@1
|
140 }
|
pang@1
|
141
|
paulo@4
|
142 return EXIT_OK;
|
pang@1
|
143 }
|