aat

git mirror of https://ccx.te2000.cz/bzr/aat
git clone https://ccx.te2000.cz/git/aat
Log | Files | Refs | README

query.awk (3021B)


      1 #!/bin/awk -f
      2 BEGIN {
      3 	in_string = 0
      4 }
      5 
      6 function out(str) {
      7 	if(length(str)) {
      8 		printf "%s", str
      9 		last_out = str
     10 	}
     11 }
     12 
     13 # called for expanding {< >}
     14 # global variable expand_remaining used as input
     15 function expand_query(    expanded) {
     16 	if(DEBUG) printf "E: →%s←\n", expand_remaining >"/dev/stderr"
     17 	expanded = ""
     18 	while(match(expand_remaining, "['<>]")) {
     19 		if(RSTART > 1) {
     20 			expanded = expanded "\"" substr(expand_remaining, 1, RSTART-1) "\""
     21 			if(DEBUG) printf "e: →%s←\n", expanded >"/dev/stderr"
     22 		}
     23 		char = substr(expand_remaining, RSTART, 1)
     24 		expand_remaining = substr(expand_remaining, RSTART+1)
     25 		if(char == ">")
     26 			return "get("expanded")"
     27 		else if(char == "<") {
     28 			expanded = expanded expand_query()
     29 			if(DEBUG) printf "e: →%s←\n", expanded >"/dev/stderr"
     30 		} else if(char == "'") {
     31 			if(match(expand_remaining, "'")) {
     32 				expanded = expanded "(" substr(expand_remaining, 1, RSTART-1) ")"
     33 				if(DEBUG) printf "e: →%s←\n", expanded >"/dev/stderr"
     34 				expand_remaining = substr(expand_remaining, RSTART+1)
     35 			} else {
     36 				expanded = expanded "(" expand_remaining ")"
     37 				if(DEBUG) printf "e: →%s←\n", expanded >"/dev/stderr"
     38 				expand_remaining = ""
     39 			}
     40 		} else {
     41 			print "ERROR: internal error in expand_query()" >"/dev/stderr"
     42 			exit 1
     43 		}
     44 	}
     45 	if(expand_remaining) {
     46 		expanded = expanded "\"" expand_remaining "\""
     47 		if(DEBUG) printf "e: →%s←\n", expanded >"/dev/stderr"
     48 		expand_remaining = ""
     49 	}
     50 	return "get("expanded")"
     51 }
     52 
     53 function parse_line(line) {
     54 	while(length(line)) {
     55 		if(DEBUG) printf "%d: →%s←\n", in_string, line >"/dev/stderr"
     56 		if(in_string) {
     57 			if(match(line, /^(\\.|[^"\\])+/)) {
     58 				out(substr(line, 1, RLENGTH))
     59 				line = substr(line, RLENGTH+1)
     60 			}
     61 			if(match(line, /^"/)) {
     62 				out("\"")
     63 				line = substr(line, 2)
     64 				in_string = 0
     65 			} else if(match(line, /^\\$/)) {
     66 				out("\\")
     67 				line = ""
     68 			} else if(!line) {
     69 				# is this valid?
     70 			} else {
     71 				print "string parsing error" >"/dev/stderr"
     72 				if(DEBUG) printf "%d: →%s←\n", in_string, line >"/dev/stderr"
     73 				exit 1
     74 			}
     75 		} else if(match(line, /^#/)) {
     76 			out(line)
     77 			line = ""
     78 		} else if(match(line, /[<"]/)) {
     79 			out(substr(line, 1, RSTART-1))
     80 			line = substr(line, RSTART)
     81 			if(match(line, /^"/)) {
     82 				line = substr(line, 2)
     83 				in_string = 1
     84 				out("\"")
     85 			} else {
     86 				if(DEBUG) printf "q: →%s← →%s←\n", last_out, line >"/dev/stderr"
     87 				if( \
     88 					match(last_out, /[[( \n\t]$/) && \
     89 					match(line, /^<([a-zA-Z0-9._<>]|'[^']*')*>/) \
     90 				) {
     91 					expand_remaining = substr(line, 2, RLENGTH-2)
     92 					line = substr(line, RLENGTH+1)
     93 					out(expand_query())
     94 				} else if(match(line, /^<[^<"]*/)) {
     95 					if(DEBUG) printf("SKIP: →%s← →%s← →%s←\n", last_out, \
     96 						substr(line, 1, RLENGTH), substr(line, RLENGTH+1) \
     97 						) >"/dev/stderr"
     98 					out(substr(line, 1, RLENGTH))
     99 					line = substr(line, RLENGTH+1)
    100 				} else {
    101 					out(line)
    102 					line = ""
    103 				}
    104 			}
    105 		} else {
    106 			out(line)
    107 			line = ""
    108 		}
    109 	}
    110 	out("\n")
    111 }
    112 
    113 { parse_line($0) }