]> git.plutz.net Git - shellwiki/commitdiff
macro execution
authorPaul Hänsch <paul@plutz.net>
Sun, 20 Feb 2022 23:42:04 +0000 (00:42 +0100)
committerPaul Hänsch <paul@plutz.net>
Sun, 20 Feb 2022 23:42:04 +0000 (00:42 +0100)
md_macros.awk

index a1e6450f48a8136dc53ad17a9cbe5c1443ea6089..7e1548235479ad9a733591559775e2c8d990b03b 100755 (executable)
@@ -1,18 +1,60 @@
 #!/bin/awk -f
 #!/opt/busybox/awk -f
 
-function macro(call, LOCAL, line, files, n, exec) {
-  "cd " ENVIRON["MD_MACROS"] "; printf '%s/' *" |getline line;
+function sh_escape(arg){
+  return "'" gensub(/'/, "'\"'\"'", "g", arg) "'";
+}
+
+function argsplit(line, args, LOCAL, c, n, ctx) {
+  ctx="space"; n=0;
+
+  while ( length(line) > 0 ) {
+    c = substr(line, 1, 1);
+    line = substr(line, 2);
+    if (ctx == "space" )
+           if (c ~ /[ \t]/) ctx = "space";
+      else if (c ~ /\\/) { n++; ctx = "escbare"; }
+      else if (c ~ /"/)  { n++; ctx = "dquot"; }
+      else if (c ~ /'/)  { n++; ctx = "squot"; }
+      else   { n++; args[n] = c; ctx = "bare"; }
+    else if (ctx == "bare")
+           if (c ~ /[ \t]/) ctx = "space";
+      else if (c ~ /\\/)  ctx = "escbare";
+      else if (c ~ /"/)   ctx = "dquot";
+      else if (c ~ /'/)   ctx = "squot";
+      else args[n] = args[n] c;
+    else if (ctx == "dquot")
+           if (c ~ /"/)  ctx = "bare";
+      else if (c ~ /\\/) ctx = "escdquot";
+      else args[n] = args[n] c;
+    else if (ctx == "squot")
+      if (c ~ /'/)  ctx = "bare";
+      else args[n] = args[n] c;
+    else if (ctx == "escbare") {
+      args[n] = args[n] c;
+      ctx = "bare";
+    }
+    else if (ctx == "escdquot") {
+      args[n] = args[n] c;
+      ctx = "dquot";
+    }
+  }
+} 
+
+function macro(call, LOCAL, line, files, n, args) {
+  "cd " sh_escape(ENVIRON["MD_MACROS"]) "; printf '%s/' *" |getline line;
   split(line, files, "/");
   for (n in files) { files[files[n]] = ""; delete files[n]; }
   delete files[""];
 
-  split(call, exec);
+  argsplit(call, args);
+  call="";
+
+  for (n = 1; n in args; n++) call = call sh_escape(args[n]) " ";
 
-  if (exec[1] in files) {
+  if (args[1] in files) {
     RS=""; ORS=""; line="";
-    # TODO: proper shell-exec function with argument array
-    "printf '%s' " line " | " ENVIRON["MD_MACROS"] "/" call | getline line;
+    "printf '%s' " sh_escape(file) " | " sh_escape(ENVIRON["MD_MACROS"]) "/" call | getline line;
     return line;
   } else {
     return HTML("<<" call ">>");