[dev] Re: [PATCH] sbase: add cut

From: Strake <strake888_AT_gmail.com>
Date: Wed, 1 Aug 2012 09:42:39 -0500

So, the new version, cut.c only, all else same:

diff -r 8cf300476909 cut.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cut.c Wed Aug 01 09:41:11 2012 -0500
_AT_@ -0,0 +1,188 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <utf.h>
+#include "text.h"
+#include "util.h"
+
+typedef struct {
+ int min, max;
+} range;
+
+int inRange (range r, unsigned int n) {
+ if ((0 == r.max || n <= r.max) && n >= r.min) return 1;
+ else return 0;
+}
+
+int fputrune (Rune r, FILE *f) {
+ char x[UTFmax];
+ int n;
+ n = runetochar (x, &r);
+ fwrite (x, 1, n, f);
+ return n;
+}
+
+void cutLineF (Rune d, unsigned int s, range *rs, char *x) {
+ int ii, n, nMax;
+ char **xs;
+ if (!utfrune (x, d)) {
+ if (!s) fputs (x, stdout);
+ return;
+ }
+ xs = malloc (sizeof (char *) * (strlen (x) + 2));
+ if (!xs) eprintf ("cut:");
+ for (n = 1; x; n++) {
+ xs[n] = x;
+ x = utfrune (x, d);
+ if (x) x += runelen (d);
+ }
+ nMax = n;
+ xs[nMax] = xs[0] + strlen (xs[0]);
+ for (ii = 0; rs[ii].min; ii++) {
+ if (nMax <= rs[ii].min) continue;
+ for (n = rs[ii].min; (rs[ii].max ? n <= rs[ii].max : 1) && n < nMax; n++) {
+ char ch = *xs[n+1];
+ *xs[n+1] = 0;
+ fputs (xs[n], stdout);
+ *xs[n+1] = ch;
+ }
+ }
+ free (xs);
+}
+
+void cutLineC (range *rs, char *x) {
+ Rune _r;
+ int ii, n;
+ for (ii = 0; rs[ii].min; ii++) {
+ char *y;
+ y = x;
+ for (n = 1; *y; n++) {
+ int l = chartorune (&_r, y);
+ if (inRange (rs[ii], n)) fwrite (y, 1, l, stdout);
+ y += l;
+ }
+ }
+}
+
+void cutLineB (range *rs, char *x) {
+ int ii, n;
+ for (ii = 0; rs[ii].min; ii++) {
+ for (n = rs[ii].min - 1; rs[ii].max ? n < rs[ii].max : x[n]; n++) {
+ fputc (x[n], stdout);
+ }
+ }
+}
+
+void go (int mode, Rune d, unsigned int s, range *rs, FILE *f) {
+ char *x;
+ size_t size = 0;
+ x = 0;
+
+ while (afgets (&x, &size, f)) {
+ int ii;
+ /* must delete newline here, and redo later;
+ otherwise, unknown whether it was included in cut */
+ for (ii = 0; x[ii]; ii++) if (x[ii] == '\n') x[ii] = 0;
+ switch (mode) {
+ case 'f':
+ if (!utfrune (x, d)) {
+ if (s) break;
+ fputs (x, stdout);
+ }
+ else cutLineF (d, s, rs, x);
+ fputc ('\n', stdout);
+ break;
+ case 'c': cutLineC (rs, x); fputc ('\n', stdout); break;
+ case 'b': cutLineB (rs, x); fputc ('\n', stdout); break;
+ }
+ }
+}
+
+int main (int argc, char *argu[]) {
+ int mode = 0;
+ Rune d = '\t';
+ unsigned int s = 0;
+ range *rs = 0;
+ int ii;
+
+ /* parse options */
+ for (ii = 1; ii < argc; ii++) {
+ int jj;
+ if (argu[ii][0] != '-' || argu[ii][1] == 0) break;
+ if (argu[ii][1] == '-' && argu[ii][2] == 0) {
+ ii++;
+ break;
+ }
+ for (jj = 1; argu[ii][jj]; jj++) switch (argu[ii][jj]) {
+ case 'b':
+ case 'c':
+ case 'f':
+ mode = argu[ii][jj];
+
+ if (++ii >= argc) {
+ fputs ("cut: No range argument\n", stderr);
+ return 1;
+ }
+
+ rs = malloc (sizeof (range) * (utflen (argu[ii]) + 1));
+ if (!rs) eprintf ("cut:");
+
+ /* ensure space delimitation for strtoul */
+ for (jj = 0; argu[ii][jj]; jj++) if (argu[ii][jj] == ',')
argu[ii][jj] = ' ';
+
+ /* parse ranges */
+ /* max = 0 to denote last */
+ {
+ char *p;
+ p = argu[ii];
+ jj = 0;
+ while (*p) {
+ rs[jj].min = *p == '-' ? 1 : strtoul (p, &p, 10);
+ rs[jj].max = *p == '-' ? strtoul (++p, &p, 10) : rs[jj].min;
+ switch (*p) {
+ case '\0':
+ rs[++jj].min = 0;
+ break;
+ case ' ':
+ case '\f':
+ case '\v':
+ case '\t':
+ case '\r':
+ case '\n':
+ jj++;
+ break;
+ default:
+ fputs ("cut: Malformed ranges\n", stderr);
+ return 1;
+ }
+ }
+ }
+ goto nextArgument;
+ case 'd':
+ chartorune (&d, argu[++ii]);
+ goto nextArgument;
+ case 's':
+ s = 1;
+ break;
+ }
+nextArgument: ;
+ }
+
+ if (!mode) {
+ fputs ("cut: No mode given\n", stderr);
+ return 1;
+ }
+
+ if (ii < argc) {
+ for (; ii < argc; ii++) {
+ FILE *f;
+ f = strcmp ("-", argu[ii]) == 0 ? stdin : fopen (argu[ii], "r");
+ if (!f) eprintf ("cut: %s:", argu[ii]);
+ go (mode, d, s, rs, f);
+ if (f != stdin) fclose (f);
+ }
+ }
+ else go (mode, d, s, rs, stdin);
+
+ return 0;
+}
Received on Wed Aug 01 2012 - 16:42:39 CEST

This archive was generated by hypermail 2.3.0 : Wed Aug 01 2012 - 16:48:03 CEST