aat

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

data.awk (3820B)


      1 #!/bin/awk -f
      2 BEGIN {
      3 	FS="\t"
      4 	SUBSEP="."
      5 	state = 0
      6 	# 0 read normal variables
      7 	# 1 seen start of field list, read titles
      8 	# 2 reading list values
      9 	# ident_re = /[a-zA-Z_][a-zA-Z0-9_]*/
     10 	ident_re = "[a-zA-Z_][a-zA-Z0-9_]*"
     11 }
     12 
     13 $0 == "]" && state == 2 {
     14 	# end of field list
     15 	state = 0
     16 	next
     17 }
     18 
     19 state == 2 {
     20 	V[varname,++V[varname,"rows"]] = $0
     21 	next
     22 }
     23 
     24 state == 1 {
     25 	if((varname, "fields") in V) {
     26 		if(V[varname,"fields"] != $0) {
     27 			print "data.awk: differing field definition for '"varname"'" >"/dev/stderr"
     28 			print "previous: '"V[varname,"fields"]"'" >"/dev/stderr"
     29 			print "current:  '"$0"'" >"/dev/stderr"
     30 			exit 1
     31 		}
     32 	}
     33 	V[varname,"fields"] = $0
     34 	state = 2
     35 	next
     36 }
     37 
     38 /^del[ \t].*[a-zA-Z_][a-zA-Z0-9_.]$/ {
     39 	del_pattern = substr($0, 5)
     40 	for(varname in V) {
     41 		if (match(varname, del_pattern)) {
     42 			delete V[varname]
     43 		}
     44 	}
     45 }
     46 
     47 /^[a-zA-Z_][a-zA-Z0-9_.]*=\[$/ {
     48 	# start of field list
     49 	state = 1
     50 	m = match($0, ident_re)
     51 	varname = substr($0, m, RLENGTH)
     52 	next
     53 }
     54 
     55 /^[a-zA-Z_][a-zA-Z0-9_.]*=/ {
     56 	m = match($0, ident_re)
     57 	varname = substr($0, m, RLENGTH)
     58 	V[varname] = substr($0, m+1+RLENGTH)
     59 	if(DEBUG) printf "got scalar: %s = %s (%d)\n", varname, V[varname], m >"/dev/stderr"
     60 	next
     61 }
     62 
     63 /^\t/ {
     64 	V[varname] = V[varname] "\n" substr($0, 1)
     65 	next
     66 }
     67 
     68 /^#/ { next }
     69 /^$/ { next }
     70 
     71 {
     72 	# TODO posix compliance
     73 	print "data.awk: unparseable line: '"$0"'" >"/dev/stderr"
     74 	exit 1
     75 }
     76 
     77 function data_not_found_error(varname, type) {
     78 	if(ENVIRON["DATA_AWK_EMPTY_GET"]) {
     79 		if(DEBUG) {
     80 			print type" not found: " varname >"/dev/stderr"
     81 		}
     82 	} else {
     83 		print "error: undefined "type" '"varname"'" >"/dev/stderr"
     84 		exit 1
     85 	}
     86 }
     87 
     88 function loop_start(varname, prefix,    depth) {
     89 	if(!((varname, "fields") in V)) {
     90 		data_not_found_error(varname, "table")
     91 	}
     92 	depth = ++loop_stack["depth"]
     93 	loop_stack[depth,"row"] = 0
     94 	loop_stack[depth,"var"] = varname
     95 	loop_stack[depth,"pre"] = prefix
     96 	return depth
     97 }
     98 
     99 function loop_iter(depth) {
    100 	loop_stack[depth,"row"]++
    101 	return (loop_stack[depth,"var"], loop_stack[depth,"row"]) in V
    102 }
    103 
    104 function loop_end() {
    105 	delete loop_stack[loop_stack["depth"], "row"]
    106 	delete loop_stack[loop_stack["depth"], "var"]
    107 	delete loop_stack[loop_stack["depth"], "pre"]
    108 	loop_stack["depth"]--
    109 }
    110 
    111 function find(varname,   i, n, names, values, loopvar, looprow, prefix) {
    112 	for(i=loop_stack["depth"]; i>0; i--) {
    113 		prefix = loop_stack[i, "pre"]
    114 		if(prefix)
    115 			if(substr(varname, 1, length(prefix)) != prefix)
    116 				continue
    117 		loopvar = loop_stack[i, "var"]
    118 		looprow = loop_stack[i, "row"]
    119 		if(varname == prefix"_index") {
    120 			found = looprow
    121 			return 1
    122 		}
    123 		if(varname == prefix"_index0") {
    124 			found = looprow - 1
    125 			return 1
    126 		}
    127 		if(varname == prefix"_revindex") {
    128 			found = V[loopvar, "rows"] - looprow + 1
    129 			return 1
    130 		}
    131 		if(varname == prefix"_revindex0") {
    132 			found = V[loopvar, "rows"] - looprow
    133 			return 1
    134 		}
    135 		if(varname == prefix"_first") {
    136 			found = looprow == 1
    137 			return 1
    138 		}
    139 		if(varname == prefix"_last") {
    140 			found = looprow == V[loopvar, "rows"]
    141 			return 1
    142 		}
    143 		if(varname == prefix"_length") {
    144 			found = V[loopvar, "rows"]
    145 			return 1
    146 		}
    147 		split(V[loopvar, "fields"], names)
    148 		for(n in names) {
    149 			if(varname == (prefix names[n])) {
    150 				split(V[loopvar, looprow], values)
    151 				found = values[n]
    152 				return 1
    153 			}
    154 		}
    155 	}
    156 	if(!(varname in V)) {
    157 		return 0
    158 	}
    159 	found = V[varname]
    160 	return 1
    161 }
    162 
    163 function get(varname) {
    164 	if(!find(varname)) {
    165 		data_not_found_error(varname, "scalar")
    166 		found = ""
    167 	}
    168 	if(DEBUG) {
    169 		print "get →" varname "← = →"found"←" >"/dev/stderr"
    170 	}
    171 	return found
    172 }
    173 
    174 function or_(a, b) {
    175 	return a ? a : b
    176 }
    177 
    178 END {
    179 	if(DEBUG) {
    180 		print "--- loaded keys ---" >"/dev/stderr"
    181 		for(key in V) {
    182 			printf("%s\t→%s←\n", key, V[key]) >"/dev/stderr"
    183 			printf(">> %d →%s←\n", find(key), found) >"/dev/stderr"
    184 		}
    185 		print "-------------------" >"/dev/stderr"
    186 	}
    187 }