repo: uritools
action: commit
revision: 
path_from: 
revision_from: a0ef1e229f20ea97d5538c8c4a8f1b6045af0c0c:
path_to: 
revision_to: 
git.thebackupbox.net
uritools
git clone git://git.thebackupbox.net/uritools
commit a0ef1e229f20ea97d5538c8c4a8f1b6045af0c0c
Author: epoch 
Date:   Sun Nov 14 04:26:25 2021 +0000

    urimatchpairs is new, urigetline got rewritten in C and WEW is it fast now. compare with .sh version.

diff --git a/urigetline b/urigetline
deleted file mode 100755
index 3f6bb51bfc274d2aeadd0fae8a0e96fe9359ad9d..0000000000000000000000000000000000000000
--- a/urigetline
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/bin/bash
-uri="$1"
-### old way.
-# line="$(grep "^${scheme}:" ~/.config/uristart.conf | cut -d: -f2- | sed 's/^[ \t]*//g' | sed 's/\\/\\\\/g')"
-
-if [ ! "$uristart_config" ];then
-  uristart_config=~/.config/uristart.conf
-fi
-
-### fancy way.
-grep '^[^#]' "$uristart_config" \
-  | while read -r l;do
-        uritmp="$uri"
-        uritmp="$(printf "%s\n" "$l" \
-          | cut -d: -f1 \
-          | tr ' ' '\n' \
-          | paste '-d ' - - \
-          | while read -r a b;do
-                uritmp="$(printf "%s\n" "${uritmp}" | urimatch "$a" "$b")"
-                printf "%s\n" "$uritmp"
-            done | tail -n1)"
-        if [ "$uritmp" ];then
-                printf '%s\n' "$l"
-                break
-        fi
-    done \
-  | cut -d: -f2- \
-  | sed 's/^[ \t]*//g' \
-  | sed 's/\\/\\\\/g'
diff --git a/urigetline.c b/urigetline.c
new file mode 100644
index 0000000000000000000000000000000000000000..2d6cd28a295450524684f47b24173957be224f89
--- /dev/null
+++ b/urigetline.c
@@ -0,0 +1,118 @@
+#include "uri.h"
+#include 
+#include 
+#include 
+#include 
+
+#define LINE_LENGTH 1024
+
+#define MATCH_UNEXIST 0
+#define MATCH_PATTERN 1
+#define MATCH_REVERSE -1
+
+// return 1 if the match and rule should have the main function print this URL.
+int match(char rule,char *part,char *arg) {
+ switch(rule) {
+  case MATCH_UNEXIST:
+   if(part == 0) return 1;
+   break;
+  case MATCH_REVERSE:
+   if(part) {
+     if(!fnmatch(arg,part,FNM_NOESCAPE)) return 0;
+     else return 1;
+   }
+   break;
+  case MATCH_PATTERN:
+   if(part) if(!fnmatch(arg,part,FNM_NOESCAPE)) return 1;
+   break;
+  default:
+   fprintf(stderr,"oh god. what the hell happened to get here?\n");
+   break;
+ }
+ return 0;
+}
+
+int main(int argc,char *argv[]) {//argument needs to be the URI
+  int j;
+  int ret=1;
+  struct uri u;
+  char matches;
+  char rule=MATCH_PATTERN;
+  char *line=malloc(LINE_LENGTH);
+  char *a,*b,*c;
+  char *command;
+  char all=0;
+  if(argc > 1) {
+    if(!strcmp(argv[1],"-a")) {
+      all=1;
+      argv++;
+      argc--;
+    }
+  }
+  if(argc < 2) {
+   fprintf(stderr,"usage: urigetline [-a] uri < uristart.conf\n");
+   return 1;
+  }
+  urifromline(&u,argv[1]);//only argv[1] is a URI?
+  while(fgets(line,LINE_LENGTH-1,stdin)) {//each line comes from the config. we need to split it on spaces.
+    if(strchr(line,'\r')) *strchr(line,'\r')=0;
+    if(strchr(line,'\n')) *strchr(line,'\n')=0;
+    if(*line == '#') continue; //skip this line too. comment.
+    if((command=strchr(line,':'))) {
+      *command=0;
+      command++;
+      while(*command == '\t') command++;
+    } else continue;//skip this line. needs at least one : to work..
+    a=line;
+    matches=1;
+    for(;a;) {
+      rule=MATCH_PATTERN;
+      j=0;
+      switch(a[0]) {
+        case '-': j=1; rule=MATCH_PATTERN; break;
+        case 'n': j=1; rule=MATCH_UNEXIST; break;
+        case 'r': j=1; rule=MATCH_REVERSE; break;
+        default: break;
+      }
+      b=0;
+      c=0;
+      if(rule != MATCH_UNEXIST) {
+        if(!(b=strchr(a,' '))) {
+          fprintf(stderr,"argument '%s' wants a value in the next argument and didn't get it. throwing a fit.\n",a);
+          return 2;
+        }
+        *b=0; b++;
+        if((c=strchr(b,' '))) {//not required
+          *c=0; c++;
+        }
+      } else {
+        if((c=strchr(a,' '))) {
+          *c=0; c++;
+        }
+      }
+      switch(a[j]) {
+        case 's': if(!match(rule,u.scheme,b))       { matches=0;} break;
+        case 'u': if(!match(rule,u.username,b))     { matches=0;} break;
+        case 'k': if(!match(rule,u.password,b))     { matches=0;} break;
+        case 'd': if(!match(rule,u.domain,b))       { matches=0;} break;
+        case 'P': if(!match(rule,u.port,b))         { matches=0;} break;
+        case 'p': if(!match(rule,u.path,b))         { matches=0;} break;
+        case 'q': if(!match(rule,u.query_string,b)) { matches=0;} break;
+        case 'f': if(!match(rule,u.fragment_id,b))  { matches=0;} break;
+          break;
+        default:
+          fprintf(stderr,"unknown url part letter! %s\n",a);
+          return 3;
+      }
+      //if(b) printf("two: %s %s\n",a,b);
+      //else printf("one: %s\n",a);
+      a=c;
+    }
+    if(matches) {
+      //printf("comm: %s\n",command);
+      printf("%s\n",command);
+      if(!all) return ret;//bail early if we only need first match
+    }
+  }
+  return ret;
+}
diff --git a/urigetline.sh b/urigetline.sh
new file mode 100755
index 0000000000000000000000000000000000000000..8589880e8fe76682e54356d959e0daf6fae1bbf4
--- /dev/null
+++ b/urigetline.sh
@@ -0,0 +1,60 @@
+#!/bin/bash
+### this script reads a config from stdin
+### and does multiple urimatches on the uri argument.
+### can optionall use -a to output all matching.
+### stdin format is:
+### [^\t]+:[ \t]+command\n
+
+if [ "$1" = "-a" ];then
+  all=1
+  shift
+fi
+uri="$1"
+### old way.
+# line="$(grep "^${scheme}:" ~/.config/uristart.conf | cut -d: -f2- | sed 's/^[ \t]*//g' | sed 's/\\/\\\\/g')"
+
+### going to use urimatchpairs until I get the whole thing rewritten in C
+grep '^[^#]' \
+  | while read -r l;do
+      uritmp="$uri"
+      uritmp="$(urimatchpairs $(printf "%s\n" "$l" | cut -d: -f1) \
+        | while read -r a b;do
+            #printf "pair: '%s' '%s'\n" "$a" "$b" >&2
+            uritmp="$(printf "%s\n" "${uritmp}" | urimatch $a $b)"
+            printf "%s\n" "${uritmp}"
+          done | tail -n1)"
+      if [ "$uritmp" ];then
+          #printf 'matching line: %s\n' "$l" >&2
+          printf "%s\n" "$l"
+          if [ ! "$all" ];then
+               break
+          fi
+      fi
+    done \
+  | cut -d: -f2- \
+  | sed 's/^[ \t]*//g' \
+  | sed 's/\\/\\\\/g'
+
+### previous version that doesn't work right for some of the match syntaxes
+#grep '^[^#]' \
+#  | while read -r l;do
+#        uritmp="$uri"
+#        uritmp="$(printf "%s\n" "$l" \
+#          | cut -d: -f1 \
+#          | tr ' ' '\n' \
+#          | paste '-d ' - - \
+#          | while read -r a b;do
+#                uritmp="$(printf "%s\n" "${uritmp}" | urimatch $a $b)"
+#                printf "%s\n" "$uritmp"
+#            done | tail -n1)"
+#        if [ "$uritmp" ];then
+#                printf 'matching line: %s\n' "$l" >&2
+#                printf '%s\n' "$l"
+#                if [ ! "$all" ]; then
+#                        break
+#	        fi
+#        fi
+#    done \
+#  | cut -d: -f2- \
+#  | sed 's/^[ \t]*//g' \
+#  | sed 's/\\/\\\\/g'
diff --git a/urimatchpairs.c b/urimatchpairs.c
new file mode 100644
index 0000000000000000000000000000000000000000..6da5d927516306796aca9f85930599c52363e358
--- /dev/null
+++ b/urimatchpairs.c
@@ -0,0 +1,23 @@
+#include 
+
+int main(int argc,char *argv[]) {
+  int i,j;
+  for(i=1;i

-----END OF PAGE-----