Hey, here's a patch that adds support to the -d, -f and -i flags to sort.
The added code uses libutf for string comparisons when the flags are used.

---
 sort.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 61 insertions(+)

diff --git a/sort.c b/sort.c
index 0761d0f..f6339cd 100644
--- a/sort.c
+++ b/sort.c
@@ -23,6 +23,9 @@ enum {
        MOD_STARTB = 1 << 1,
        MOD_ENDB   = 1 << 2,
        MOD_R      = 1 << 3,
+       MOD_D      = 1 << 4,
+       MOD_F      = 1 << 5,
+       MOD_I      = 1 << 6,
 };
 
 static TAILQ_HEAD(kdhead, keydef) kdhead = TAILQ_HEAD_INITIALIZER(kdhead);
@@ -116,6 +119,44 @@ columns(char *line, const struct keydef *kd, char **col, 
size_t *colsiz)
 }
 
 static int
+skipmodcmp(const char *s1, const char *s2, int flags)
+{
+       Rune r1, r2;
+
+       do {
+               s1 += chartorune(&r1, s1);
+               s2 += chartorune(&r2, s2);
+
+               if (flags & MOD_D && flags & MOD_I) {
+                       while (*s1 && ((!isblankrune(r1) && !isalnumrune(r1)) ||
+                                                  (!isprintrune(r1))))
+                               s1 += chartorune(&r1, s1);
+                       while (*s2 && ((!isblankrune(r2) && !isalnumrune(r2)) ||
+                                                  (!isprintrune(r2))))
+                               s2 += chartorune(&r2, s2);
+               }
+               else if (flags & MOD_D) {
+                       while (*s1 && !isblankrune(r1) && !isalnumrune(r1))
+                               s1 += chartorune(&r1, s1);
+                       while (*s2 && !isblankrune(r2) && !isalnumrune(r2))
+                               s2 += chartorune(&r2, s2);
+               }
+               else if (flags & MOD_I) {
+                       while (*s1 && !isprintrune(r1))
+                               s1 += chartorune(&r1, s1);
+                       while (*s2 && !isprintrune(r2))
+                               s2 += chartorune(&r2, s2);
+               }
+               if (flags & MOD_F) {
+                       r1 = tolowerrune(r1);
+                       r2 = tolowerrune(r2);
+               }
+       } while (r1 && r1 == r2);
+
+       return r1 - r2;
+}
+
+static int
 linecmp(const char **a, const char **b)
 {
        int res = 0;
@@ -135,6 +176,8 @@ linecmp(const char **a, const char **b)
                        x = strtold(col1, NULL);
                        y = strtold(col2, NULL);
                        res = (x < y) ? -1 : (x > y);
+               } else if (kd->flags & (MOD_D | MOD_F | MOD_I)) {
+                       res = skipmodcmp(col1, col2, kd->flags);
                } else {
                        res = strcmp(col1, col2);
                }
@@ -178,6 +221,15 @@ parse_flags(char **s, int *flags, int bflag)
                case 'b':
                        *flags |= bflag;
                        break;
+               case 'd':
+                       *flags |= MOD_D;
+                       break;
+               case 'f':
+                       *flags |= MOD_F;
+                       break;
+               case 'i':
+                       *flags |= MOD_I;
+                       break;
                case 'n':
                        *flags |= MOD_N;
                        break;
@@ -263,6 +315,15 @@ main(int argc, char *argv[])
        case 'c':
                cflag = 1;
                break;
+       case 'd':
+               global_flags |= MOD_D;
+               break;
+       case 'f':
+               global_flags |= MOD_F;
+               break;
+       case 'i':
+               global_flags |= MOD_I;
+               break;
        case 'k':
                addkeydef(EARGF(usage()), global_flags);
                break;
-- 
2.1.4


Reply via email to