1 /* 2 * Copyright (c) 2016, 2019 Daichi GOTO 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #define FILEPROCESS_RETU { \ 29 FILE *fp_fp; \ 30 int fp_no_output = 0; \ 31 int fp_b = 0, fp_r_i = 1; \ 32 int fp_buf_i, fp_buf_len; \ 33 char *fp_buf, *fp_p = NULL, *fp_newbuf, *fp_buf_end; \ 34 fp_buf_len = BUFFER_SIZE; \ 35 fp_buf = calloc(fp_buf_len, sizeof(char)); \ 36 for (int fp_file_i = 1; fp_file_i <= F_ARGC; fp_file_i++) { \ 37 fp_fp = fopen(F_ARGV[fp_file_i], "r"); \ 38 if (NULL == fp_fp) \ 39 err(errno, "%s", F_ARGV[fp_file_i]); \ 40 while (EOF != (fp_b = fgetc(fp_fp))) { \ 41 fp_p = fp_buf; \ 42 fp_buf_i = 0; \ 43 fp_buf_end = &fp_buf[fp_buf_len - 1]; \ 44 *fp_p = fp_b; \ 45 while (' ' != *fp_p && \ 46 '\n' != *fp_p && EOF != *fp_p) { \ 47 ++fp_p; \ 48 ++fp_buf_i; \ 49 FILEPROCESS_RETU_BUFFER_EXPANSION \ 50 *fp_p = fgetc(fp_fp); \ 51 } \ 52 if ((' ' == fp_b && *fp_p == fp_b) || \ 53 ('\n' == fp_b && *fp_p == fp_b)) { \ 54 *fp_p = '@'; \ 55 ++fp_p; \ 56 ++fp_buf_i; \ 57 FILEPROCESS_RETU_BUFFER_EXPANSION \ 58 } \ 59 else { \ 60 fp_b = *fp_p; \ 61 } \ 62 *fp_p = '\0'; \ 63 if (fp_r_i <= R_INDEX_MAX && \ 64 R_INDEX_EXIST[fp_r_i]) { \ 65 TGT_RETU_PROCESS(fp_buf,fp_buf_len,fp_r_i) \ 66 } \ 67 else { \ 68 NOTGT_RETU_PROCESS(fp_buf,fp_buf_len,fp_r_i) \ 69 } \ 70 switch (fp_b) { \ 71 case ' ': \ 72 if (!fp_no_output) putchar(' '); \ 73 ++fp_r_i; \ 74 break; \ 75 case '\n': \ 76 case EOF: \ 77 if (!fp_no_output) putchar('\n'); \ 78 fp_r_i = 1; \ 79 END_OF_LINE_RETU_PROCESS \ 80 break; \ 81 } \ 82 } \ 83 fclose(fp_fp); \ 84 } \ 85 } 86 87 #define FILEPROCESS_RETU_BUFFER_EXPANSION { \ 88 if (fp_p == fp_buf_end) { \ 89 fp_newbuf = \ 90 calloc(fp_buf_len + BUFFER_SIZE, sizeof(char)); \ 91 if (NULL == fp_newbuf) \ 92 err(errno, "ttt_utils.h#FILEPROCESS_RETU"); \ 93 memcpy(fp_newbuf, fp_buf, fp_buf_len * sizeof(char)); \ 94 fp_buf_len += BUFFER_SIZE; \ 95 free(fp_buf); \ 96 fp_buf = fp_newbuf; \ 97 fp_buf_end = &fp_buf[fp_buf_len - 1]; \ 98 fp_p = &fp_buf[fp_buf_i]; \ 99 } \ 100 } 101 102 #define FILEPROCESS_GYO { \ 103 FILE *fp_fp; \ 104 struct stat fp_sb; \ 105 int fp_b = 0, fp_r_i = 1, fled = 0; \ 106 int fp_buf_i, fp_buf_len, fp_ibuf_len, fp_nf; \ 107 char *fp_buf, *fp_buf_end, **fp_ibuf; \ 108 char *fp_p = NULL, *fp_newbuf, **fp_newibuf; \ 109 int *r_index_to_argv, *r_index_exist, r_index_max; \ 110 fp_buf_len = BUFFER_SIZE; \ 111 fp_ibuf_len = 32; \ 112 fp_buf = calloc(fp_buf_len, sizeof(char)); \ 113 fp_ibuf = calloc(fp_ibuf_len + 1, sizeof(char *)); \ 114 for (int fp_file_i = 1; \ 115 fp_file_i <= F_ARGC; fp_file_i++) { \ 116 fp_fp = fopen(F_ARGV[fp_file_i], "r"); \ 117 if (NULL == fp_fp) \ 118 err(errno, "%s", F_ARGV[fp_file_i]); \ 119 stat(F_ARGV[fp_file_i], &fp_sb); \ 120 fp_p = fp_buf; \ 121 fp_buf_i = fp_nf = 0; \ 122 fp_buf_end = &fp_buf[fp_buf_len - 1]; \ 123 while (1) { \ 124 fp_b = fgetc(fp_fp); \ 125 if (EOF == fp_b) { \ 126 if (fled) { fled = 0; break; } \ 127 else fp_nf -= 1; \ 128 } \ 129 fled = 0; \ 130 *fp_p = fp_b; \ 131 while (' ' != *fp_p && \ 132 '\n' != *fp_p && EOF != *fp_p) { \ 133 ++fp_p; \ 134 ++fp_buf_i; \ 135 FILEPROCESS_GYO_BUFFER_EXPANSION \ 136 *fp_p = fgetc(fp_fp); \ 137 } \ 138 if ((' ' == fp_b && *fp_p == fp_b) || \ 139 ('\n' == fp_b && *fp_p == fp_b) || \ 140 (EOF == fp_b && *fp_p == fp_b)) { \ 141 *fp_p = '@'; \ 142 ++fp_p; \ 143 ++fp_buf_i; \ 144 FILEPROCESS_GYO_BUFFER_EXPANSION \ 145 } \ 146 else { \ 147 fp_b = *fp_p; \ 148 } \ 149 *fp_p = '\0'; \ 150 ++fp_nf; \ 151 switch (fp_b) { \ 152 case ' ': \ 153 ++fp_p; \ 154 ++fp_buf_i; \ 155 FILEPROCESS_GYO_BUFFER_EXPANSION \ 156 ++fp_r_i; \ 157 break; \ 158 case '\n': \ 159 fled = 1; \ 160 case EOF: \ 161 fp_r_i = 1; \ 162 FILEPROCESS_GYO_IBUFFER_EXPANSION \ 163 FILEPROCESS_GYO_IBUFFER_ASSIGN \ 164 FILEPROCESS_GYO_R_INDEX_EXPANSION \ 165 TGT_GYO_PROCESS(fp_ibuf,fp_nf) \ 166 fp_p = fp_buf; \ 167 fp_buf_i = fp_nf = 0; \ 168 break; \ 169 } \ 170 if (EOF == fp_b) \ 171 break; \ 172 } \ 173 fclose(fp_fp); \ 174 } \ 175 } 176 177 #define FILEPROCESS_GYO_FILESIZE_IS_ZERO \ 178 0 == fp_sb.st_size 179 180 #define FILEPROCESS_GYO_BUFFER_EXPANSION { \ 181 if (fp_p == fp_buf_end) { \ 182 fp_newbuf = \ 183 calloc(fp_buf_len + BUFFER_SIZE, sizeof(char)); \ 184 if (NULL == fp_newbuf) \ 185 err(errno, \ 186 "ttt_utils.h#" \ 187 "FILEPROCESS_GYO_BUFFER_EXPANSION"); \ 188 memcpy(fp_newbuf, fp_buf, fp_buf_len * sizeof(char)); \ 189 fp_buf_len += BUFFER_SIZE; \ 190 free(fp_buf); \ 191 fp_buf = fp_newbuf; \ 192 fp_buf_end = &fp_buf[fp_buf_len - 1]; \ 193 fp_p = &fp_buf[fp_buf_i]; \ 194 } \ 195 } 196 197 #define FILEPROCESS_GYO_IBUFFER_EXPANSION { \ 198 if (fp_ibuf_len < fp_nf) { \ 199 fp_newibuf = calloc(fp_nf + 1, sizeof(char *)); \ 200 if (NULL == fp_newibuf) \ 201 err(errno, \ 202 "ttt_utils.h#" \ 203 "FILEPROCESS_GYO_IBUFFER_EXPANSION"); \ 204 memcpy(fp_newibuf, fp_ibuf, fp_ibuf_len * sizeof(char *)); \ 205 fp_ibuf_len = fp_nf; \ 206 free(fp_ibuf); \ 207 fp_ibuf = fp_newibuf; \ 208 } \ 209 } 210 211 #define FILEPROCESS_GYO_IBUFFER_ASSIGN { \ 212 fp_p = fp_buf; \ 213 fp_ibuf[1] = fp_buf; \ 214 for (int fp_i = 2; fp_i <= fp_nf; fp_i++) { \ 215 while ('\0' != *fp_p) { \ 216 ++fp_p; \ 217 } \ 218 ++fp_p; \ 219 fp_ibuf[fp_i] = fp_p; \ 220 } \ 221 } 222 223 #define FILEPROCESS_GYO_R_INDEX_EXPANSION { \ 224 if (R_INDEX_MAX < fp_nf) { \ 225 r_index_max = fp_nf; \ 226 r_index_to_argv = \ 227 calloc(r_index_max + 1, sizeof(int)); \ 228 if (NULL == r_index_to_argv) \ 229 err(errno, \ 230 "ttt_utils.h#" \ 231 "FILEPROCESS_GYO_R_INDEX_EXPANSION"); \ 232 memcpy(r_index_to_argv, R_INDEX_TO_ARGV, \ 233 (r_index_max + 1) * sizeof(int)); \ 234 for (int fp_i = R_INDEX_MAX + 1; \ 235 fp_i <= r_index_max + 1; fp_i++) \ 236 r_index_to_argv[fp_i] = R_INDEX_IS_NONE; \ 237 free(R_INDEX_TO_ARGV); \ 238 R_INDEX_TO_ARGV = r_index_to_argv; \ 239 ; \ 240 r_index_exist = calloc(r_index_max + 1, sizeof(int)); \ 241 if (NULL == r_index_exist) \ 242 err(errno, \ 243 "ttt_utils.h#" \ 244 "FILEPROCESS_GYO_R_INDEX_EXPANSION"); \ 245 memcpy(r_index_exist, R_INDEX_EXIST, \ 246 (r_index_max + 1) * sizeof(int)); \ 247 for (int fp_i = R_INDEX_MAX + 1; \ 248 fp_i <=r_index_max + 1; fp_i++) \ 249 r_index_exist[fp_i] = R_INDEX_IS_NOT_EXISTENCE; \ 250 free(R_INDEX_EXIST); \ 251 R_INDEX_EXIST = r_index_exist; \ 252 R_INDEX_MAX = r_index_max; \ 253 } \ 254 } 255 256 #define FILEPROCESS_CHAR { \ 257 FILE *fp_fp; \ 258 int fp_b = 0; \ 259 for (int fp_file_i = 1; fp_file_i <= F_ARGC; fp_file_i++) { \ 260 fp_fp = fopen(F_ARGV[fp_file_i], "r"); \ 261 if (NULL == fp_fp) \ 262 err(errno, "%s", F_ARGV[fp_file_i]); \ 263 while (1) { \ 264 fp_b = fgetc(fp_fp); \ 265 TGT_CHAR_PROCESS(fp_b) \ 266 if (EOF == fp_b) \ 267 break; \ 268 } \ 269 fclose(fp_fp); \ 270 } \ 271 } 272 273 #define FILEPROCESS_CAT { \ 274 FILE *fp_fp; \ 275 int fp_b = 0; \ 276 char fp_bpre; \ 277 for (int fp_file_i = 1; fp_file_i <= F_ARGC; fp_file_i++) { \ 278 fp_fp = fopen(F_ARGV[fp_file_i], "r"); \ 279 if (NULL == fp_fp) \ 280 err(errno, "%s", F_ARGV[fp_file_i]); \ 281 while (1) { \ 282 fp_b = fgetc(fp_fp); \ 283 if (EOF == fp_b) { \ 284 if ('\n' != fp_bpre) \ 285 putchar('\n'); \ 286 break; \ 287 } \ 288 putchar(fp_b); \ 289 fp_bpre = fp_b; \ 290 } \ 291 fclose(fp_fp); \ 292 } \ 293 } 294 295 #define FILEPROCESS_ALLBUFFER { \ 296 int fp_fd, fp_size, fp_rsize; \ 297 struct stat fp_st; \ 298 char *fp_buf; \ 299 for (int fp_file_i = 1; fp_file_i <= F_ARGC; fp_file_i++) { \ 300 if (-1 == stat(F_ARGV[fp_file_i], &fp_st )) \ 301 err(errno, "%s", F_ARGV[fp_file_i]); \ 302 fp_size = fp_st.st_size; \ 303 fp_buf = calloc(fp_size + 1, sizeof(char)); \ 304 if (-1 == (fp_fd = open(F_ARGV[fp_file_i], O_RDONLY))) \ 305 err(errno, "%s", F_ARGV[fp_file_i]); \ 306 fp_rsize = 0; \ 307 while (fp_rsize != fp_size) \ 308 fp_rsize += read(fp_fd, fp_buf+fp_rsize, \ 309 fp_size-fp_rsize); \ 310 TGT_BUFFER_PROCESS(fp_buf, fp_size) \ 311 free(fp_buf); \ 312 close(fp_fd); \ 313 } \ 314 } 315