#!/bin/awk -f BEGIN { in_string = 0 } function out(str) { if(length(str)) { printf "%s", str last_out = str } } # called for expanding {< >} # global variable expand_remaining used as input function expand_query( expanded) { if(DEBUG) printf "E: →%s←\n", expand_remaining >"/dev/stderr" expanded = "" while(match(expand_remaining, "['<>]")) { if(RSTART > 1) { expanded = expanded "\"" substr(expand_remaining, 1, RSTART-1) "\"" if(DEBUG) printf "e: →%s←\n", expanded >"/dev/stderr" } char = substr(expand_remaining, RSTART, 1) expand_remaining = substr(expand_remaining, RSTART+1) if(char == ">") return "get("expanded")" else if(char == "<") { expanded = expanded expand_query() if(DEBUG) printf "e: →%s←\n", expanded >"/dev/stderr" } else if(char == "'") { if(match(expand_remaining, "'")) { expanded = expanded "(" substr(expand_remaining, 1, RSTART-1) ")" if(DEBUG) printf "e: →%s←\n", expanded >"/dev/stderr" expand_remaining = substr(expand_remaining, RSTART+1) } else { expanded = expanded "(" expand_remaining ")" if(DEBUG) printf "e: →%s←\n", expanded >"/dev/stderr" expand_remaining = "" } } else { print "ERROR: internal error in expand_query()" >"/dev/stderr" exit 1 } } if(expand_remaining) { expanded = expanded "\"" expand_remaining "\"" if(DEBUG) printf "e: →%s←\n", expanded >"/dev/stderr" expand_remaining = "" } return "get("expanded")" } function parse_line(line) { while(length(line)) { if(DEBUG) printf "%d: →%s←\n", in_string, line >"/dev/stderr" if(in_string) { if(match(line, /^(\\.|[^"\\])+/)) { out(substr(line, 1, RLENGTH)) line = substr(line, RLENGTH+1) } if(match(line, /^"/)) { out("\"") line = substr(line, 2) in_string = 0 } else if(match(line, /^\\$/)) { out("\\") line = "" } else if(!line) { # is this valid? } else { print "string parsing error" >"/dev/stderr" if(DEBUG) printf "%d: →%s←\n", in_string, line >"/dev/stderr" exit 1 } } else if(match(line, /^#/)) { out(line) line = "" } else if(match(line, /[<"]/)) { out(substr(line, 1, RSTART-1)) line = substr(line, RSTART) if(match(line, /^"/)) { line = substr(line, 2) in_string = 1 out("\"") } else { if(DEBUG) printf "q: →%s← →%s←\n", last_out, line >"/dev/stderr" if( \ match(last_out, /[[( \n\t]$/) && \ match(line, /^<([a-zA-Z0-9._<>]|'[^']*')*>/) \ ) { expand_remaining = substr(line, 2, RLENGTH-2) line = substr(line, RLENGTH+1) out(expand_query()) } else if(match(line, /^<[^<"]*/)) { if(DEBUG) printf("SKIP: →%s← →%s← →%s←\n", last_out, \ substr(line, 1, RLENGTH), substr(line, RLENGTH+1) \ ) >"/dev/stderr" out(substr(line, 1, RLENGTH)) line = substr(line, RLENGTH+1) } else { out(line) line = "" } } } else { out(line) line = "" } } out("\n") } { parse_line($0) }