]> mj.ucw.cz Git - xsv.git/commitdiff
Added --trim
authorMartin Mares <mj@ucw.cz>
Mon, 23 Jul 2012 18:27:08 +0000 (20:27 +0200)
committerMartin Mares <mj@ucw.cz>
Mon, 23 Jul 2012 18:27:08 +0000 (20:27 +0200)
xsv.c

diff --git a/xsv.c b/xsv.c
index 38f1fdeac88088859fae44f2835f080f971a4fbe..87c8dff8966fceaf2b1f1a2f5ee0c349f5205cca 100644 (file)
--- a/xsv.c
+++ b/xsv.c
@@ -128,6 +128,11 @@ restart:
        }
 }
 
+static int is_ws(int c)
+{
+       return (c == ' ' || c == '\t' || c == '\f');
+}
+
 static void csv_write(void)
 {
        unsigned char *line = line_nth(&in_line, 0);
@@ -171,7 +176,7 @@ static int ws_read(void)
                        continue;
                if (c == '\n')
                        return 1;
-               if (c == ' ' || c == '\t' || c == '\f') {
+               if (is_ws(c)) {
                        ensure_field();
                        if (!ws)
                                new_field();
@@ -185,6 +190,20 @@ static int ws_read(void)
        }
 }
 
+/*** Transforms ***/
+
+static void trim_fields(void)
+{
+       unsigned char *line = line_nth(&in_line, 0);
+       for (int i = 0; i < fields_count(&in_fields); i++) {
+               struct field *f = fields_nth(&in_fields, i);
+               while (f->len && is_ws(line[f->start_pos]))
+                       f->start_pos++, f->len--;
+               while (f->len && is_ws(line[f->start_pos + f->len - 1]))
+                       f->len--;
+       }
+}
+
 /*** Field selection ***/
 
 struct selector {
@@ -250,10 +269,10 @@ Formats:\n\
 -w, --ws               Values separated by arbitrary whitespace\n\
 \n\
 Format parameters:\n\
--d, --fs=<char>        Delimiter of fields\n\
+-d, --fs=<char>                Delimiter of fields\n\
 \n\
 Other options:\n\
-(so far none)\n\
+    --trim             Trim leading and trailing whitespaces in fields\n\
 ");
        exit(0);
 }
@@ -270,11 +289,13 @@ static const char short_options[] = "cd:tw";
 
 enum long_options {
        OPT_HELP = 256,
+       OPT_TRIM = 257,
 };
 
 static const struct option long_options[] = {
        { "csv",                0,      NULL,   'c' },
        { "fs",                 1,      NULL,   'd' },
+       { "trim",               0,      NULL,   OPT_TRIM },
        { "tsv",                0,      NULL,   't' },
        { "ws",                 0,      NULL,   'w' },
        { "help",               0,      NULL,   OPT_HELP },
@@ -329,6 +350,7 @@ static struct format *current_format(void)
 int main(int argc, char **argv)
 {
        int opt;
+       int want_trim = 0;
 
        while ((opt = getopt_long(argc, argv, short_options, long_options, NULL)) >= 0)
                switch (opt) {
@@ -349,6 +371,9 @@ int main(int argc, char **argv)
                                break;
                        case OPT_HELP:
                                usage();
+                       case OPT_TRIM:
+                               want_trim = 1;
+                               break;
                        default:
                                bad_args(NULL);
                }
@@ -375,6 +400,9 @@ int main(int argc, char **argv)
                if (!in_format->read_line())
                        break;
 
+               if (want_trim)
+                       trim_fields();
+
                fields_reset(&out_fields);
                select_fields();