comparison ed.c @ 3:ac52712b2b5e

Remove the fspec(5) tabulator support We don't want such bloat in ed(1)!
author markus schnalke <meillo@marmaro.de>
date Sun, 12 Apr 2015 21:45:34 +0200
parents a09d0630f05b
children 4165f1b57d18
comparison
equal deleted inserted replaced
2:a09d0630f05b 3:ac52712b2b5e
66 #include <time.h> 66 #include <time.h>
67 #include <string.h> 67 #include <string.h>
68 #include <stdlib.h> 68 #include <stdlib.h>
69 #include <signal.h> 69 #include <signal.h>
70 #include "sigset.h" 70 #include "sigset.h"
71 #include <termios.h>
72 #include <setjmp.h> 71 #include <setjmp.h>
73 #include <libgen.h> 72 #include <libgen.h>
74 #include <inttypes.h> 73 #include <inttypes.h>
75 #include <locale.h> 74 #include <locale.h>
76 #include <wchar.h> 75 #include <wchar.h>
77 #include <ctype.h> 76 #include <ctype.h>
78 #include <wctype.h> 77 #include <wctype.h>
79 #include <limits.h> 78 #include <limits.h>
80 #include <termios.h>
81 static int FNSIZE; 79 static int FNSIZE;
82 static int LBSIZE; 80 static int LBSIZE;
83 static int RHSIZE; 81 static int RHSIZE;
84 #define ESIZE 2048 82 #define ESIZE 2048
85 static int GBSIZE; 83 static int GBSIZE;
96 #define BLKMSK (MAXCNT>>8) /* was 0377 */ 94 #define BLKMSK (MAXCNT>>8) /* was 0377 */
97 95
98 #define READ 0 96 #define READ 0
99 #define WRITE 1 97 #define WRITE 1
100 #define EXIST 2 98 #define EXIST 2
101
102 struct tabulator {
103 struct tabulator *t_nxt; /* next list element */
104 const char *t_str; /* tabulator string */
105 int t_tab; /* tab stop position */
106 int t_rep; /* repetitive tab count */
107 };
108 99
109 static int peekc; 100 static int peekc;
110 static int lastc; 101 static int lastc;
111 static char *savedfile; 102 static char *savedfile;
112 static char *file; 103 static char *file;
164 static int readop; 155 static int readop;
165 static int status; 156 static int status;
166 static int mb_cur_max; 157 static int mb_cur_max;
167 static int needsub; 158 static int needsub;
168 static int insub; 159 static int insub;
169 static struct tabulator *tabstops;
170 static int maxlength; 160 static int maxlength;
171 static int rspec; 161 static int rspec;
172 static int Nflag; 162 static int Nflag;
173 static int bcount = 22; 163 static int bcount = 22;
174 static int ocount = 11; 164 static int ocount = 11;
233 static void undo(void); 223 static void undo(void);
234 static int maketf(int); 224 static int maketf(int);
235 static int creatf(const char *); 225 static int creatf(const char *);
236 static int sopen(const char *, int); 226 static int sopen(const char *, int);
237 static void sclose(int); 227 static void sclose(int);
238 static void fspec(const char *);
239 static const char *ftok(const char **);
240 static struct tabulator *tabstring(const char *);
241 static void freetabs(void);
242 static void expand(const char *);
243 static void growlb(const char *); 228 static void growlb(const char *);
244 static void growrhs(const char *); 229 static void growrhs(const char *);
245 static void growfn(const char *); 230 static void growfn(const char *);
246 static void help(void); 231 static void help(void);
247 232
1125 linebuf[i++] = c ? c : '\n'; 1110 linebuf[i++] = c ? c : '\n';
1126 count++; 1111 count++;
1127 } while (c != '\n'); 1112 } while (c != '\n');
1128 linebuf[--i] = 0; 1113 linebuf[--i] = 0;
1129 nextj = j; 1114 nextj = j;
1130 if (rspec && dot == zero)
1131 fspec(linebuf);
1132 if (maxlength && i > maxlength) { 1115 if (maxlength && i > maxlength) {
1133 putstr("line too long: lno = "); 1116 putstr("line too long: lno = ");
1134 putd((dot - zero+1)&MAXCNT); 1117 putd((dot - zero+1)&MAXCNT);
1135 putchr('\n'); 1118 putchr('\n');
1136 } 1119 }
1967 static void 1950 static void
1968 nlputs(register const char *sp) 1951 nlputs(register const char *sp)
1969 { 1952 {
1970 if (listf) 1953 if (listf)
1971 list(sp); 1954 list(sp);
1972 else if (tabstops)
1973 expand(sp);
1974 else 1955 else
1975 puts(sp); 1956 puts(sp);
1976 } 1957 }
1977 1958
1978 static void 1959 static void
2232 pipid = -1; 2213 pipid = -1;
2233 } 2214 }
2234 readop = 0; 2215 readop = 0;
2235 } 2216 }
2236 2217
2237 static void
2238 fspec(const char *lp)
2239 {
2240 struct termios ts;
2241 const char *cp;
2242
2243 freetabs();
2244 maxlength = 0;
2245 if (tcgetattr(1, &ts) < 0
2246 #ifdef TAB3
2247 || (ts.c_oflag&TAB3) == 0
2248 #endif
2249 )
2250 return;
2251 while (lp[0]) {
2252 if (lp[0] == '<' && lp[1] == ':')
2253 break;
2254 lp++;
2255 }
2256 if (lp[0]) {
2257 lp += 2;
2258 while ((cp = ftok(&lp)) != NULL) {
2259 switch (*cp) {
2260 case 't':
2261 freetabs();
2262 if ((tabstops = tabstring(&cp[1])) == NULL)
2263 goto err;
2264 break;
2265 case 's':
2266 maxlength = atoi(&cp[1]);
2267 break;
2268 case 'm':
2269 case 'd':
2270 case 'e':
2271 break;
2272 case ':':
2273 if (cp[1] == '>') {
2274 if (tabstops == NULL)
2275 if ((tabstops = tabstring("0"))
2276 == NULL)
2277 goto err;
2278 return;
2279 }
2280 /*FALLTHRU*/
2281 default:
2282 err: freetabs();
2283 maxlength = 0;
2284 errput("PWB spec problem", NULL);
2285 return;
2286 }
2287 }
2288 }
2289 }
2290
2291 static const char *
2292 ftok(const char **lp)
2293 {
2294 const char *cp;
2295
2296 while (**lp && **lp != ':' && (**lp == ' ' || **lp == '\t'))
2297 (*lp)++;
2298 cp = *lp;
2299 while (**lp && **lp != ':' && **lp != ' ' && **lp != '\t')
2300 (*lp)++;
2301 return cp;
2302 }
2303
2304 static struct tabulator *
2305 repetitive(int repetition)
2306 {
2307 struct tabulator *tp, *tabspec;
2308 int col, i;
2309
2310 if ((tp = tabspec = calloc(1, sizeof *tp)) == NULL)
2311 return NULL;
2312 tp->t_rep = repetition;
2313 if (repetition > 0) {
2314 for (col = 1+repetition, i = 0; i < 22; col += repetition) {
2315 if ((tp->t_nxt = calloc(1, sizeof *tp)) == NULL)
2316 return NULL;
2317 tp = tp->t_nxt;
2318 tp->t_tab = col;
2319 }
2320 }
2321 return tabspec;
2322 }
2323
2324 #define blank(c) ((c) == ' ' || (c) == '\t')
2325
2326 static struct tabulator *
2327 tablist(const char *s)
2328 {
2329 struct tabulator *tp, *tabspec;
2330 char *x;
2331 int prev = 0, val;
2332
2333 if ((tp = tabspec = calloc(1, sizeof *tp)) == NULL)
2334 return NULL;
2335 for (;;) {
2336 while (*s == ',')
2337 s++;
2338 if (*s == '\0' || blank(*s) || *s == ':')
2339 break;
2340 val = strtol(s, &x, 10);
2341 if (*s == '+')
2342 val += prev;
2343 prev = val;
2344 if (*s == '-' || (*x != ',' && !blank(*x) && *x != ':' &&
2345 *x != '\0'))
2346 return NULL;
2347 s = x;
2348 if ((tp->t_nxt = calloc(1, sizeof *tp)) == NULL)
2349 return NULL;
2350 tp = tp->t_nxt;
2351 tp->t_tab = val;
2352 }
2353 return tabspec;
2354 }
2355
2356 static struct tabulator *
2357 tabstring(const char *s)
2358 {
2359 const struct {
2360 const char *c_nam;
2361 const char *c_str;
2362 } canned[] = {
2363 { "a", "1,10,16,36,72" },
2364 { "a2", "1,10,16,40,72" },
2365 { "c", "1,8,12,16,20,55" },
2366 { "c2", "1,6,10,14,49" },
2367 { "c3", "1,6,10,14,18,22,26,30,34,38,42,46,50,54,58,62,67" },
2368 { "f", "1,7,11,15,19,23" },
2369 { "p", "1,5,9,13,17,21,25,29,33,37,41,45,49,53,57,61" },
2370 { "s", "1,10,55" },
2371 { "u", "1,12,20,44" },
2372 { 0, 0 }
2373 };
2374
2375 int i, j;
2376
2377 if (s[0] == '-') {
2378 if (s[1] >= '0' && s[1] <= '9' && ((i = atoi(&s[1])) != 0))
2379 return repetitive(i);
2380 for (i = 0; canned[i].c_nam; i++) {
2381 for (j = 0; canned[i].c_nam[j]; j++)
2382 if (s[j+1] != canned[i].c_nam[j])
2383 break;
2384 if ((s[j+1]=='\0' || s[j+1]==':' || blank(s[j+1])) &&
2385 canned[i].c_nam[j] == '\0')
2386 return tablist(canned[i].c_str);
2387 }
2388 return NULL;
2389 } else
2390 return tablist(s);
2391 }
2392
2393 static void
2394 freetabs(void)
2395 {
2396 struct tabulator *tp;
2397
2398 tp = tabstops;
2399 while (tp) {
2400 tabstops = tp->t_nxt;
2401 free(tp);
2402 tp = tabstops;
2403 }
2404 }
2405
2406 static void
2407 expand(const char *s)
2408 {
2409 struct tabulator *tp = tabstops;
2410 int col = 0, n = 1, m, tabcnt = 0, nspc;
2411 wchar_t wc;
2412
2413 while (*s) {
2414 nspc = 0;
2415 switch (*s) {
2416 case '\n':
2417 putchr('\0');
2418 s++;
2419 continue;
2420 case '\t':
2421 if (tp) {
2422 if (tp->t_rep) {
2423 if (col % tp->t_rep == 0) {
2424 nspc++;
2425 col++;
2426 }
2427 while (col % tp->t_rep) {
2428 nspc++;
2429 col++;
2430 }
2431 break;
2432 }
2433 while (tp && (col>tp->t_tab || tp->t_tab == 0))
2434 tp = tp->t_nxt;
2435 if (tp && col == tp->t_tab) {
2436 nspc++;
2437 col++;
2438 tp = tp->t_nxt;
2439 }
2440 if (tp) {
2441 while (col < tp->t_tab) {
2442 nspc++;
2443 col++;
2444 }
2445 tp = tp->t_nxt;
2446 break;
2447 }
2448 }
2449 tabcnt = 1;
2450 nspc++;
2451 break;
2452 default:
2453 if (mb_cur_max>1 && (n=mbtowc(&wc, s, mb_cur_max))>0) {
2454 if ((m = wcwidth(wc)) > 0)
2455 col += m;
2456 } else {
2457 col++;
2458 n = 1;
2459 }
2460 }
2461 if (maxlength && col > maxlength) {
2462 putstr("\ntoo long");
2463 break;
2464 }
2465 if (nspc) {
2466 while (nspc--)
2467 putchr(' ');
2468 s++;
2469 } else
2470 while (n--)
2471 putchr(*s++);
2472 }
2473 if (tabcnt)
2474 putstr("\ntab count");
2475 putchr('\n');
2476 }
2477
2478 static wint_t 2218 static wint_t
2479 GETWC(char *mb) 2219 GETWC(char *mb)
2480 { 2220 {
2481 int c, n; 2221 int c, n;
2482 2222