add option -upgrade

add option -upgrade

--- include/Main.awk
+++ include/Main.awk
@@ -198,6 +198,13 @@
             continue
         }

+        # -U, -upgrade
+        match(ARGV[pos], /^--?(U|upgrade)$/)
+        if (RSTART) {
+            InfoOnly = "upgrade"
+            continue
+        }
+
         # -N, -nothing
         match(ARGV[pos], /^--?(N|nothing)$/)
         if (RSTART) {
@@ -575,6 +582,9 @@
     case "list":
         print getList(Option["tl"])
         exit
+    case "upgrade":
+        upgrade()
+        exit
     case "nothing":
         exit
     }


cleaning global.e1.params.ttl with bin/util/update-e-params-subject-discrim.awk

--- bin/util/update-e-params-subject-discrim.awk
+++ bin/util/update-e-params-subject-discrim.awk
@@ -10,11 +10,11 @@
 {
    if( $1 == "@prefix" && $2 == ":" ) {
       # Fix up default namespace.
-      printf("@prefix :           <%s/source/%s/dataset/%s/version/%s/params/enhancement/%s/> .",baseURI,sourceID,dataset_identifier,);
+      printf("@prefix :           <%s/source/%s/dataset/%s/version/%s/params/enhancement/%s/> .",baseURI,sourceID,dataset_identifier,datasetVersion,layerID);

    }else if( $0 == ":dataset a void:Dataset;" ) {
       # Change subject to name of layer dataset itself.
-      printf("%s/source/%s/dataset/%s/version/%s/conversion/enhancement/%s",baseURI,sourceID,dataset_identifier,datasetVersion,$layerID);
+      printf("%s/source/%s/dataset/%s/version/%s/conversion/enhancement/%s",baseURI,sourceID,dataset_identifier,datasetVersion,layerID);

    }else if( $0~"conversion:subject_discriminator" ) {
       printf("      conversion:subject_discriminator \"%s\";\n",subjectDiscriminator)


Fix dependencies generation

Fix dependencies generation

--- far/scripts/mkdep.awk
+++ far/scripts/mkdep.awk
@@ -46,6 +46,8 @@
       for (i in force_include)
         print " " force_include[i];
     }
+    else if (ext == obj)
+        print " disabled_warnings.hpp"
   }
   else
   {


Translate: handle 301 redirection via curl() (often HTTPS)


Update min/max messaging

Update min/max messaging

--- bin/bawlk.awk
+++ bin/bawlk.awk
@@ -146,8 +146,8 @@

         cat         = "error"
         test        = field " != \"\" && " field " " comparator " " limit
-        mini_msg    = "value should be " term " than: " limit
-        msg         = field " in \" CSVFILENAME \" line \" NR \" should be " term " than " limit " and was \" " field " \" "
+        mini_msg    = "value should be " term " or equal to: " limit
+        msg         = field " in \" CSVFILENAME \" line \" NR \" should be " term " or equal to" limit " and was \" " field " \" "

     } else if (rule_type == "pattern") {
         pattern     = params[2]
@@ -165,7 +165,7 @@
         cat         = "error"
         test        = field " != \"\" && length(" field ") " comparator " " limit
         mini_msg    = "max length is: " limit
-        msg         = field " length in \" CSVFILENAME \" line \" NR \" should be " term " than " limit " and was \" length(" field ") \" "
+        msg         = field " length in \" CSVFILENAME \" line \" NR \" should be " term " or equal to " limit " and was \" length(" field ") \" "
     }
 }


reworked to improve splitting namespace from id

--- scripts/ntriple2dot.awk
+++ scripts/ntriple2dot.awk
@@ -13,28 +13,46 @@
 # which may belong to a "structural" ontology as opposed to
 # a data uri.

-#  Perhaps an improvement would be to to also
+#  Perhaps an improvement would be to also
 # express subject and objects as individual curies (ala predicates)
 # iff their namespace is also used by a predicate.

 ##########################################################
-# remove first and last chars from input
+# remove first and last chars from input string <>
 function trim(str){
 	return substr(str,2,length(str)-2)
 }

-# remove final element in slashed path
-# this leaves the namespace of the removed identifier
+########################################################
+# remove final(ish) element in paths with various delimiters
+# this leaves the namespace of a removed identifier
+
+# this may need to be called more than once since
+# some identifiers may have embedded delimiters
 function stripid(uri){
-	l = match(uri,/.*\//)  # side effect is RLENGTH
-	if(l<=0)
+	# <_:blanknode> are not allowed in ntriples (but may happen anyway)
+	if(1 == match(uri, /^_:/))
+		return "BNODE"
+	# perspective endpoints, choose the longest
+	delim["_"]=0; delim["/"]=0;
+	delim["="]=0; delim[":"]=0; delim["#"]=0;
+	char=""; max=-1;
+	for(c in delim){
+		l = match(uri, char)  # side effect is RLENGTH
+		if(l > max){
+			char = c;
+			delim[char] = RLENGTH
+		}
+	}
+	if(max<=0) # we don't know what it is, a literal perhaps or uri fragment
 		return uri
 	else
-		return substr(uri,1,RLENGTH-1)
+		return substr(uri,1,delim[char])  # the probably truncated uri
 }

 # keep underscore, letters & numbers
 # change the rest to (a single) underscore sans leading & trailing
+# this passes valid node labels from dot's perspective
 function simplify(str){
 	gsub(/[^[:alpha:][:digit:]_]+/,"_",str)
 	gsub(/^_+|_+$/, "",str)
@@ -44,15 +62,19 @@

 # if possible, find a shorter form for the input
 function contract(uri){
-	if(uri in prefix)
-		return prefix[uri]
+	u = uri
+	# shorten till longest uri in curi map is found (or not)
+	while(!(u in prefix) && (0 < length(u)))
+		u = stripid(substr(u,1,length(u)-1))
+
+	if(u in prefix)
+		return prefix[u]
 	else
 		for(ex in exception){
-			start = match(uri, ex)
-			if(0 < start)
-				return exception[substr(uri, start, RLENGTH)]
+			if(0 < match(uri, ex))
+				return exception[substr(uri, 1, RLENGTH)]
 		}
-		return simplify(uri)
+		return "___" simplify(uri)
 }

 # get the final (incl fragment identifier) portion of a slashed path
@@ -66,16 +88,13 @@
 }

 BEGIN{
-	# Monarchinitiave's dipper ingest files have cases
-	# which escape the general rules
-	# in everything
-	exception["http://www.w3.org/2002/07"]="OWL_"
-	exception["http://www.w3.org/1999/02"]="RDF"
-	exception["http://www.w3.org/2000/01"]="RDFS"
-	# in go,mgi,wormbase
-	exception["http://dx.doi.org"]="DOI"
+	prefix["BNODE"] = "BNODE"  # is a fixed point
+	# revisit if exceptions are still necessary
+	exception["http://www.w3.org/1999/02/22-rdf-syntax-ns#"]="rdf"
+	exception["http://www.w3.org/2000/01/rdf-schema#"]="rdfs"
+	exception["http://www.w3.org/2002/07/owl#"]="owl"
 	# in mgi
-	exception["https://www.mousephenotype.org"]="IMPC_"
+	exception["https://www.mousephenotype.org"]="IMPC"
 	# in panther
 	exception["http://identifiers.org/wormbase"]="WormBase"
 	# just until skolemized bnodes get in the curie map?
@@ -85,10 +104,13 @@
 }

 # main loop
-# parse and stash the curie file (first file)
-(FNR == NR) && /^'[^']*' *: 'http[^']*'.*/ {
-	split($0,a,"'")
-	prefix[stripid(a[4])]=a[2]
+# parse and stash the curie yaml file (first file)
+# YAML format is tic delimited word (the curi prefix)
+# optional whitespace, a colon, then a tic delimited url
+# (FNR == NR) && /^'[^']*' *: 'http[^']*'.*/ { # loosing some?
+(FNR == NR) && /^'.*/ {
+	split($0, arr, "'")
+	prefix[arr[4]]=arr[2]
 }
 # process the ntriple file(s)  which are not the first file
 ### case when subject predicate and object are all uri
@@ -96,22 +118,22 @@
 	### Subject (uri)
 	s = contract(stripid(trim($1)))
 	### Predicate (uri)
-	q = final(trim($2))
-	p = contract(stripid(trim($2)))
+	p =  final(trim($2))
+	ns = contract(stripid(trim($2)))
 	### Object (like subject)
 	o = contract(stripid(trim($3)))
-	edgelist[s " -> " o " [label=\"" p ":" q]++
+	edgelist[s,ns ":" p,o]++
 }
 ### case when the object is a literal
 (FNR != NR) && /^<[^>]*> <[^>]*> "[^"]*" \.$/ {
 	### Subject (uri)
 	s = contract(stripid(trim($1)))
 	### Predicate (uri)
-	q = final(trim($2))
-	p = contract(stripid(trim($2)))
+	p = final(trim($2))
+	ns = contract(stripid(trim($2)))
 	### not a uri
 	o = "LITERAL"
-	edgelist[s " -> " o " [label=\"" p":"q ]++
+	edgelist[s, ns ":" p, o]++
 	nodelist[o " [shape=record];"]++
 }

@@ -120,14 +142,17 @@
 	print "digraph {"
 	print "rankdir=LR;"
 	print "charset=\"utf-8\";"
-	for(edge in edgelist) print edge " (" edgelist[edge] ")\"];"
+	for(edge in edgelist){
+		split(edge ,spo, SUBSEP);
+		print simplify(spo[1]) " -> " simplify(spo[3]) \
+		" [label=\"" spo[2] " (" edgelist[edge] ")\"];"
+	}
 	for(node in nodelist) print node
 	print "labelloc=\"t\";"
 	title = final(FILENAME)
-	now = systime()
-	# return date(1)-style output
-	datestamp = strftime("%Y%m%d", now)
+	datestamp = strftime("%Y%m%d", systime())
 	print "label=\"" substr(title,1,length(title)-3) " (" datestamp ")\";"
 	print "}"
+
 }


Close command in curl and curlPost

Close command in curl and curlPost

--- include/Utils.awk
+++ include/Utils.awk
@@ -164,6 +164,7 @@
     content = NULLSTR
     while ((command |& getline line) > 0)
         content = (content ? content "\n" : NULLSTR) line
+    close(command)
     return content
 }

@@ -192,6 +193,7 @@
     content = NULLSTR
     while ((command |& getline line) > 0)
         content = (content ? content "\n" : NULLSTR) line
+    close(command)
     return content
 }


CWS gnumake3: replacement of cygpath by variables was broken

--- solenv/gbuild/processdeps.awk
+++ solenv/gbuild/processdeps.awk
@@ -47,7 +47,7 @@
 function mangle_path(path) {
     gsub("\\\\", "/", path);
     if( path ~ /^[a-zA-Z]:/ )
-        path = toupper(substr(path,0,1)) substr(path,2);
+        path = tolower(substr(path,0,1)) substr(path,2);
     gsub(WORKDIR, "$(WORKDIR)/", path);
     gsub(OUTDIR, "$(OUTDIR)/", path);
     gsub(SRCDIR, "$(SRCDIR)/", path);
@@ -58,11 +58,15 @@
 }

 BEGIN {
+   WORKDIR = tolower(substr(WORKDIR,0,1)) substr(WORKDIR,2);
+   OUTDIR = tolower(substr(OUTDIR,0,1)) substr(OUTDIR,2);
+   SRCDIR = tolower(substr(SRCDIR,0,1)) substr(SRCDIR,2);
+   REPODIR = tolower(substr(REPODIR,0,1)) substr(REPODIR,2);
 #   print "# WORKDIR=" WORKDIR;
 #   print "# OUTDIR=" OUTDIR;
 #   print "# SRCDIR=" SRCDIR;
 #   print "# REPODIR=" REPODIR;
-    print mangle_path(OBJECTFILE) ": \\";
+   print mangle_path(OBJECTFILE) ": \\";
 }

 /^[^#]/ {


Make debian happier (cherry picked from commit eb52c44c0ce952817ff48821d037eaa6d93cd7c1)

--- smt_parse.awk
+++ smt_parse.awk
@@ -1,4 +1,4 @@
-#!/usr/bin/gawk -f
+#!/usr/bin/awk -f
 # Simplified approach: only pick out lines with round definitions
 /^\(\(round.*\)\)$/ {
 	print $0;


Help: adjust wrong alphabetical order

Help: adjust wrong alphabetical order

--- include/Help.awk
+++ include/Help.awk
@@ -95,10 +95,10 @@
             Locale["mr"]["name"] "        - " ansi("bold", "mr") "  │ " \
             Locale["yi"]["name"] "    - " ansi("bold", "yi") " │" RS \
             "│ " Locale["de"]["name"] "              - " ansi("bold", "de") "    │ " \
-            Locale["my"]["name"] "        - " ansi("bold", "my") "  │ " \
+            Locale["mn"]["name"] "      - " ansi("bold", "mn") "  │ " \
             Locale["yo"]["name"] "     - " ansi("bold", "yo") " │" RS \
             "│ " Locale["el"]["name"] "               - " ansi("bold", "el") "    │ " \
-            Locale["mn"]["name"] "      - " ansi("bold", "mn") "  │ " \
+            Locale["my"]["name"] "        - " ansi("bold", "my") "  │ " \
             Locale["zu"]["name"] "       - " ansi("bold", "zu") " │" RS \
             "│ " Locale["gu"]["name"] "            - " ansi("bold", "gu") "    │ " \
             Locale["ne"]["name"] "         - " ansi("bold", "ne") "  │ " \


Main: change default User-Agent

Main: change default User-Agent

--- include/Main.awk
+++ include/Main.awk
@@ -44,7 +44,7 @@

     # Networking
     Option["proxy"] = ENVIRON["HTTP_PROXY"] ? ENVIRON["HTTP_PROXY"] : ENVIRON["http_proxy"]
-    Option["user-agent"] = ENVIRON["USER_AGENT"] ? ENVIRON["USER_AGENT"] : "Mozilla/5.0 (X11; Linux x86_64; rv:40.0) Gecko/20100101 Firefox/40.0"
+    Option["user-agent"] = ENVIRON["USER_AGENT"] ? ENVIRON["USER_AGENT"] : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/602.1 (KHTML, like Gecko) Version/8.0 Safari/602.1 Epiphany/3.18.2"

     # Interactive shell
     Option["no-rlwrap"] = 0


REPL: update

REPL: update

--- include/REPL.awk
+++ include/REPL.awk
@@ -4,7 +4,7 @@

 # Detect external readline wrapper (rlwrap).
 function initRlwrap() {
-    Rlwrap = ("rlwrap --version" SUPERR | getline) ? "rlwrap" : ""
+    Rlwrap = detectProgram("rlwrap", "--version")
 }

 # Prompt for interactive session.


updates to support -Wextra

updates to support -Wextra

--- scripts/strconf.awk
+++ scripts/strconf.awk
@@ -1095,7 +1095,7 @@
 #endif\n\
 \n\
 #if !defined(USER)\n\
-void copying(int argc, char *argv[])\n\
+void copying()\n\
 {\n\
 	fprintf(stdout, \"\\\n\
 \\n\\\n\
@@ -1136,10 +1136,10 @@
 Commercial  licensing  and  support of this  software is  available from OpenSS7\\n\\\n\
 Corporation at a fee.  See http://www.openss7.com/\\n\\\n\
 \\n\\\n\
-\", argv[0], ident);\n\
+\", NAME, ident);\n\
 }\n\
 \n\
-void version(int argc, char *argv[])\n\
+void version()\n\
 {\n\
 	fprintf(stdout, \"\\\n\
 \\n\\\n\
@@ -1160,7 +1160,7 @@
 \", NAME, PACKAGE, VERSION);\n\
 }\n\
 \n\
-void usage(int argc, char *argv[])\n\
+void usage(char *argv[])\n\
 {\n\
 	fprintf(stderr, \"\\\n\
 Usage:\\n\\\n\
@@ -1171,7 +1171,7 @@
 \", argv[0]);\n\
 }\n\
 \n\
-void help(int argc, char *argv[])\n\
+void help(char *argv[])\n\
 {\n\
 	fprintf(stdout, \"\\\n\
 \\n\\\n\
@@ -1231,13 +1231,13 @@
 			rmopt = 1;\n\
                         break;\n\
 		case 'h':	/* -h, --help */\n\
-			help(argc, argv);\n\
+			help(argv);\n\
 			exit(0);\n\
 		case 'V':	/* -V, --version */\n\
-			version(argc, argv);\n\
+			version();\n\
 			exit(0);\n\
 		case 'C':	/* -C, --copying */\n\
-			copying(argc, argv);\n\
+			copying();\n\
 			exit(0);\n\
 		case '?':\n\
 			optind--;\n\
@@ -1248,7 +1248,7 @@
 					fprintf(stderr, \"%s \", argv[optind]);\n\
 				fprintf(stderr, \"\\n\");\n\
 			}\n\
-			usage(argc, argv);\n\
+			usage(argv);\n\
 			exit(2);\n\
 		}\n\
 	}\n\


missed the trailing digit

missed the trailing digit

--- dev/pci/drm/i915/devlist.awk
+++ dev/pci/drm/i915/devlist.awk
@@ -3,7 +3,7 @@
 	print("static const struct pci_matchid i915_devices[] = {");
 }
 /INTEL_VGA_DEVICE\(0x/ {
-	val = substr($0, 19, 5);
+	val = substr($0, 19, 6);
 	print "\t{ 0x8086,", val " },";
 }
 END {


Utils: update

Utils: update

--- include/Utils.awk
+++ include/Utils.awk
@@ -62,10 +62,11 @@
                 command = command " " parameterize(ARGV[i])

         l(">> forking: " command)
-        if (!system(command))
-            exit ExitCode # child process finished
-        else {
-            l(">> non-zero code returned from process")
+        if (!system(command)) {
+            l(">> process exited with code 0")
+            exit ExitCode
+        } else {
+            l(">> process exited with non-zero return code")
             return 1
         }
     }
@@ -99,9 +100,12 @@
         command = Emacs " --eval " parameterize(el)

         l(">> forking: " command)
-        if (!system(command))
-            exit ExitCode # child process finished
-        else
+        if (!system(command)) {
+            l(">> process exited with code 0")
+            exit ExitCode
+        } else {
+            l(">> process exited with non-zero return code")
             return 1
+        }
     }
 }


Move back. Start testing 2013 on Dec 1.

Move back. Start testing 2013 on Dec 1.

git-svn-id: 293778eaa97c8c94097d610b1bd5133a8f478f36@29223 4f837ed2-42f5-46e7-a7a5-fa17313484d4

--- scripts/tdb/statuses_gln.awk
+++ scripts/tdb/statuses_gln.awk
@@ -8,7 +8,7 @@

 {
   # add a loop to add line only if either status is _not_ manifest or ending year is gt or eq to contract year
-  current_year = 2013
+  current_year = 2012
   end_year = 0
   incontract = 0
   test_year = ""


Fix extra lines in header file

Fix extra lines in header file

--- getMHzFrom-seriesPages.awk
+++ getMHzFrom-seriesPages.awk
@@ -88,9 +88,10 @@
             sub (/"\>/,"")
             print $0 >> DESCRIPTION_FILE
             # if we didn't find a header in this block, print a blank one
-            if (headerPrinted == "no")
+            if (headerPrinted == "no") {
                 print "==> No genre/country line: " seriesTitle >> ERROR_FILE
                 print "\t\t\t" >> HEADER_FILE
+            }
         }
     }
 }


default prefixes

default prefixes

--- bin/util/header2params2.awk
+++ bin/util/header2params2.awk
@@ -68,6 +68,8 @@
       print "@prefix doap:          <http://usefulinc.com/ns/doap#> ."
       print "@prefix nfo:           <http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#> ."
       print "@prefix sio:           <http://semanticscience.org/resource/> ."
+      print "@prefix vsr:           <http://purl.org/twc/vocab/vsr#> ."
+      print "@prefix dcat:          <http://www.w3.org/ns/dcat#> ."
       print "@prefix qb:            <http://purl.org/linked-data/cube#> ."
       print "@prefix dgtwc:         <http://data-gov.tw.rpi.edu/2009/data-gov-twc.rdf#> ."
    }


Disambiguate "The Moonstone" 2016/1972

Disambiguate "The Moonstone" 2016/1972

--- getBBoxCatalogFromSitemap.awk
+++ getBBoxCatalogFromSitemap.awk
@@ -192,6 +192,17 @@
 /<\/item>/ {
     lastLineNum = NR

+    # "The Moonstone" needs to be revised to avoid duplicate names
+    if (title == "The Moonstone") {
+        if (EntityId == "_9283") {
+            revisedTitles += 1
+            printf ("==> Changed title '%s' to 'The Moonstone (2016)'\n", title) >> ERRORS
+            title = "The Moonstone (2016)"
+        }
+        # print "==> title = " title > "/dev/stderr"
+        # print "==> EntityId = " EntityId > "/dev/stderr"
+    }
+
     # "Porridge" needs to be revised to avoid duplicate names
     if (title == "Porridge") {
         if (EntityId == "_9509") {


Update to 2015.

Update to 2015.

git-svn-id: 293778eaa97c8c94097d610b1bd5133a8f478f36@42941 4f837ed2-42f5-46e7-a7a5-fa17313484d4

--- scripts/tdb/statuses_clockss.awk
+++ scripts/tdb/statuses_clockss.awk
@@ -8,7 +8,8 @@

 {
   # add a loop to add line only if either status is (wanted or testing) or ending year is gt or eq to contract year
-  current_year = 2014
+  # increased to 2015 July 1 2015.
+  current_year = 2015
   # end_year is the AU year, or the second half of a range, ie 2014 in 2013-2014
   end_year = 0
   incontract = 0


Add comments and update code to not include 2015 during 2014.

git-svn-id: 293778eaa97c8c94097d610b1bd5133a8f478f36@38854 4f837ed2-42f5-46e7-a7a5-fa17313484d4

--- scripts/tdb/statuses_clockss.awk
+++ scripts/tdb/statuses_clockss.awk
@@ -9,8 +9,10 @@
 {
   # add a loop to add line only if ending year is gt or eq to contract year
   current_year = 2014
+  # end_year is the AU year, or the second half of a range, ie 2014 in 2013-2014
   end_year = 0
   incontract = 0
+  # test_year is the contract year, or the back year if there is one.
   test_year = ""
   if ($7 == "") {
     test_year = $3
@@ -22,7 +24,7 @@
   }
   #printf "%s\t%s\t%s\t%s\t%s\t%s\t%s\n", $1,$2,$3,$4,$7,end_year,test_year
   if (end_year >= test_year) {
-    if ((end_year < current_year) || ((end_year >= current_year) && (incl_cur == 1))) {
+    if ((end_year < current_year) || ((end_year == current_year) && (incl_cur == 1))) {
       incontract = 1
     }
   }


Add deepCrawl.

Add deepCrawl.

--- scripts/tdb/statuses_clockss.awk
+++ scripts/tdb/statuses_clockss.awk
@@ -67,14 +67,15 @@
   s[5] = "notReady"
   s[6] = "ready"
   s[7] = "crawling"
-  s[8] = "frozen"
-  s[9] = "ingNotReady"
-  s[10] = "finished"
-  s[11] = "down"
-  s[12] = "superseded"
-  s[13] = "zapped"
-  s[14] = "doNotProcess"
-  sn = 15
+  s[8] = "deepCrawl"
+  s[9] = "frozen"
+  s[10] = "ingNotReady"
+  s[11] = "finished"
+  s[12] = "down"
+  s[13] = "superseded"
+  s[14] = "zapped"
+  s[15] = "doNotProcess"
+  sn = 16

   sc[0] = "expe"
   sc[1] = "exis"
@@ -84,14 +85,15 @@
   sc[5] = "notR"
   sc[6] = "read"
   sc[7] = "craw"
-  sc[8] = "froz"
-  sc[9] = "ingN"
-  sc[10] = "fini"
-  sc[11] = "down"
-  sc[12] = "supe"
-  sc[13] = "zapp"
-  sc[14] = "doNP"
-  scn = 15
+  sc[8] = "deep"
+  sc[9] = "froz"
+  sc[10] = "ingN"
+  sc[11] = "fini"
+  sc[12] = "down"
+  sc[13] = "supe"
+  sc[14] = "zapp"
+  sc[15] = "doNP"
+  scn = 16

   #print out header
   printf "Publisher\tPlugin\tContr\tBack\tYear\tT\tTotal"


mmake/mwg_pp.awk: update

mmake/mwg_pp.awk: update

--- mmake/mwg_pp.awk
+++ mmake/mwg_pp.awk
@@ -231,7 +231,7 @@
           _w=_w _c;
         }
       }
-    }else if(_c ~ /\s/){
+    }else if(_c ~ /[[:space:]]/){
       continue; # ignore blank
     }else{
       print_error("mwg_pp.eval_expr","unrecognizable character '" _c "'");


After egg's review.

After egg's review.

--- astronomy/generate_initial_state.awk
+++ astronomy/generate_initial_state.awk
@@ -57,6 +57,12 @@

   for (i = 0; i < n; ++i) {
     b = bodies[i]
+    sub(/E/, "e", x[b])
+    sub(/E/, "e", y[b])
+    sub(/E/, "e", z[b])
+    sub(/E/, "e", vx[b])
+    sub(/E/, "e", vy[b])
+    sub(/E/, "e", vz[b])
     print "  body {"
     print "    name : \"" b "\""
     print "    x    : \"" x[b] " km\""


Duplicate keycode 50 as keycode 49, some USB keyboards use the latter.

with and ok millert@

--- dev/usb/makemap.awk
+++ dev/usb/makemap.awk
@@ -1,5 +1,5 @@
 #! /usr/bin/awk -f
-#	$OpenBSD: makemap.awk,v 1.5 2005/05/19 17:49:54 miod Exp $
+#	$OpenBSD: makemap.awk,v 1.6 2005/05/23 21:33:03 miod Exp $
 #
 # Copyright (c) 2005, Miodrag Vallat
 #
@@ -31,7 +31,7 @@
 #

 BEGIN {
-	rcsid = "$OpenBSD: makemap.awk,v 1.5 2005/05/19 17:49:54 miod Exp $"
+	rcsid = "$OpenBSD: makemap.awk,v 1.6 2005/05/23 21:33:03 miod Exp $"
 	ifdepth = 0
 	ignore = 0
 	declk = 0
@@ -299,10 +299,15 @@
 	}

 	if (haskeys) {
-		# Duplicate 42 (backspace) as 76
-		# XXX maybe not correct anymore?
-		lines[76] = lines[42]
-		sub("42", "76", lines[76])
+		# Duplicate 42 (backspace) as 76 and 50 (backslash bar) as 49
+		if (!lines[76]) {
+			lines[76] = lines[42]
+			sub("42", "76", lines[76])
+		}
+		if (!lines[49]) {
+			lines[49] = lines[50]
+			sub("50", "49", lines[49])
+		}

 		for (i = 0; i < 256; i++)
 			if (lines[i]) {


Cleaned up second awk script

Cleaned up second awk script

--- getMhzFrom-seriesPages.awk
+++ getMhzFrom-seriesPages.awk
@@ -10,7 +10,7 @@
 # INPUT:
 #       <title>A French Village - MHz Choice</title>
 #       <meta name="description" content="DRAMA | FRANCE | FRENCH WITH ENGLISH SUBTITLES | TV-MA^M
-#       This acclaimed drama is about the German...all in a day's worki... its inhabitants.">
+#       This acclaimed drama is about the German...all in a day's work... its inhabitants.">
 #
 # OUTPUT:
 #       $MARQUEE_FILE, $DESCRIPTION_FILE, $HEADER_FILE,
@@ -18,8 +18,7 @@
 #

 BEGIN {
-    numPrinted = 0
-    FS = "\|"
+    printed = "no"
 }

 /title>/ {
@@ -41,18 +40,19 @@
         sub (/NONFICTION - DOCUMENTARY/,"Documentary")
         gsub (/ \| /,"|")
         sub (/\r/,"")
-        # ensure lowercase for everything but the first character
-        # in all fields but the last
-        for (i = 1; i < NF; ++i) {
-            $i = substr($i,1,1) tolower(substr($i,2))
-            # uppercase for second of two word fields
-            if (match($i,/ /) > 0)
-                $i = substr($i,1,RSTART) toupper(substr($i,RSTART+1,1)) \
-                   (substr($i,RSTART+2))
+        # Split out header fields
+        numFields = split($0,fld,"\|")
+        # lowercase everything but the first character in all fields but the last
+        for (i = 1; i < numFields; ++i) {
+            fld[i] = substr(fld[i],1,1) tolower(substr(fld[i],2))
+            # uppercase the first character of any second word
+            if (match(fld[i],/ /) > 0)
+                fld[i] = substr(fld[i],1,RSTART) toupper(substr(fld[i],RSTART+1,1)) \
+                   (substr(fld[i],RSTART+2))
         }
         # print the finalized header
-        print $1 "\t" $2 "\t" $(NF-1) "\t" $(NF) >> HEADER_FILE
-        numPrinted += 1
+        print fld[1] "\t" fld[2] "\t" fld[(numFields-1)] "\t" fld[(numFields)] >> HEADER_FILE
+        printed = "yes"
     } else {
         # Extract the description
         gsub (/"\>/,"")
@@ -65,7 +65,7 @@
 }

 END {
-    if (numPrinted == 0)
-        printf ("\t\t\t\n") >> HEADER_FILE
+    if (printed == "no")
+        print "\t\t\t" >> HEADER_FILE
     print "" >> DESCRIPTION_FILE
 }


Create clickable URL

Create clickable URL

--- getBBoxCatalogFrom-sitemap.awk
+++ getBBoxCatalogFrom-sitemap.awk
@@ -268,7 +268,6 @@
     }

     if (contentType == "tv_season") {
-        #xxx
         countSeasons += 1
         # print "\ntv_season" > "/dev/stderr"
         for ( i = 1; i <= countShows; i++ ) {
@@ -311,14 +310,31 @@
         # print "sortkey = " sortkey > "/dev/stderr"
         # Compose title
     }
-
+
+    # Generate a link that will lead to the show on Britbox
+    # https://www.britbox.com/us/movie/A_Queen_Is_Crowned_13551
+    # https://www.britbox.com/us/movie/_13551
+    #
+    # https://www.britbox.com/us/show/All_Creatures_Great_and_Small_23737
+    # https://www.britbox.com/us/show/_23737
+    #
+    # https://www.britbox.com/us/season/All_Creatures_Great_and_Small_S2_23752
+    # https://www.britbox.com/us/season/_23752
+    #
+    # https://www.britbox.com/us/episode/All_Creatures_Great_and_Small_S2_E2_23764
+    # https://www.britbox.com/us/episode/_23764
+    showType = contentType
+    sub ("tv_","",showType)
+    URL = "https://www.britbox.com/us/" showType EntityId
+    fullTitle = "=HYPERLINK(\"" URL "\";\"" title "\")"
+
     # Copied from above to make it easier to coordinate printing fields
     # printf ("Sortkey\tTitle\tSeasons\tEpisodes\tDuration\tYear\tRating\tDescription\t")
     # printf ("Content_Type\tContent_ID\tEntity_ID\tGenre\tShow_Type\tDate_Type\tOriginal_Date\t")
     # printf ("Show_ID\tSeason_ID\tSn_#\tEp_#\t1st_#\tLast_#\n")

     printf ("%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%06d\t%06d\n",
-            sortkey, title, numSeasons, numEpisodes, duration, year, rating, description,
+            sortkey, fullTitle, numSeasons, numEpisodes, duration, year, rating, description,
             contentType, contentId, EntityId, genre, showType, dateType, originalDate,
             showContentId, seasonContentId, seasonNumber, episodeNumber, firstLineNum, lastLineNum)
 }


add option -dictionary

add option -dictionary

--- include/Main.awk
+++ include/Main.awk
@@ -179,6 +179,13 @@
         match(ARGV[pos], /^--?verbose$/)
         if (RSTART) {
             Option["verbose"] = 1 # default value
+            continue
+        }
+
+        # -d, -dictionary
+        match(ARGV[pos], /^--?d(i(c(t(i(o(n(a(ry?)?)?)?)?)?)?)?)?$/)
+        if (RSTART) {
+            Option["show-original-dictionary"] = 1
             continue
         }


Added -f option to awk so that script can be invoked manually

git-svn-id: 28d9401aa571d5108e51b194aae6f24ca5964c06@2537 8cc4aa7f-3514-0410-904f-f2cc9021211c

--- bin/memdbg.awk
+++ bin/memdbg.awk
@@ -1,4 +1,4 @@
-#!/bin/awk
+#!/bin/awk -f
 #
 # This script is intended to extract all useful information from output of
 #


MONDRIAN: Ordering rules for olap4j imports.

[git-p4: depot-paths = "//open/mondrian/": change = 14728]

--- bin/checkFile.awk
+++ bin/checkFile.awk
@@ -193,6 +193,9 @@
     }
 }

+/^package / {
+    thisPackage = $2;
+}
 /^package / && previousLineWasEmpty {
     error(fname, FNR, "'package' declaration must not occur after empty line");
 }
@@ -207,19 +210,23 @@
     thisImport = $2;
     gsub(/;/, "", thisImport);
     gsub(/\*/, "", thisImport);
-    if (thisImport ~ /^mondrian/) {
-        importGroup = "a";
+    if (thisPackage ~ /^mondrian.*/ && thisImport ~ /^mondrian.*/ \
+        || thisPackage ~ /^org.olap4j.*/ && thisImport ~ /^org.olap4j.*/)
+    {
+        importGroup = "a";
     } else if (thisImport ~ /^static/) {
         importGroup = "z";
-    } else if (thisImport ~ /^java/) {
+    } else if (thisImport ~ /^java.*/) {
         importGroup = "y";
-    } else if (thisImport ~ /^junit/) {
+    } else if (thisImport ~ /^junit.*/) {
         importGroup = "b";
-    } else if (thisImport ~ /^org.apache/) {
+    } else if (thisImport ~ /^mondrian.*/) {
+        importGroup = "bb";
+    } else if (thisImport ~ /^org.apache.*/) {
         importGroup = "c";
-    } else if (thisImport ~ /^org.eigenbase/) {
+    } else if (thisImport ~ /^org.eigenbase.*/) {
         importGroup = "d";
-    } else if (thisImport ~ /^org.olap4j/) {
+    } else if (thisImport ~ /^org.olap4j.*/) {
         importGroup = "e";
     } else {
         importGroup = "f";


addr_utils.awk		-- strip state [zip], country from reply addresses

--- lib/addr_utils.awk
+++ lib/addr_utils.awk
@@ -1,4 +1,4 @@
-function AU_parse(rply, addr, result, towns, st_types, st_quals, dirs,   nf, ary, i, town, f_st, nf2, ary2, street, i1) {
+function AU_parse(rply, addr, result, towns, st_types, st_quals, dirs,   nf, ary, i, f_st, nf2, ary2, i1, name, street, town) {

 	result["status"] = "B"
 	result["emsg"  ] = ""
@@ -7,17 +7,34 @@
 	result["town"  ] = ""
 	result["state" ] = ""

-	# TODO: rply addresses have 2 extra fields: ST[ DDDDD], United States
 	nf = split(addr, ary, ",")
+	for(i = 1; i <= nf; i++){
+		sub(/^ */, "", ary[i])
+		sub(/ *$/, "", ary[i])
+	}
+
+	if(rply){
+		if(ary[nf] != "United States of America"){
+			result["emsg"] = "not.usa"
+			return 1
+		}else
+			nf--
+		if(ary[nf] == "CA")
+			nf--
+		else if(ary[nf] ~ /CA [0-9]{5}$/)
+			nf--
+		else if(ary[nf] ~ /CA [0-9]{5}-[0-9]{4}$/)
+			nf--
+		else{
+			result["emsg"] = "not.CA"
+			return 1
+		}
+	}

 	# minimal address has 2 fields: street, town
 	if(nf < 2){
 		result["emsg"] = "short.addr"
 		return 1
-	}
-	for(i = 1; i <= nf; i++){
-		sub(/^ */, "", ary[i])
-		sub(/ *$/, "", ary[i])
 	}

 	# check that we have a known town
@@ -44,8 +61,17 @@
 		result["emsg"] = "no.street"
 		return 1
 	}
+
+	# The name is what precedes f_st.  if f_st == 1, set name to "Residence"
+	if(f_st == 1)
+		name = "Residence"
+	else{
+		name = ary[1]
+		for(i = 2; i < f_st; i++)
+			name = name ", " ary[i]
+	}

-	# TODO: reply addresses need extra though here
+	# TODO: reply addresses need extra thought here
 	# clean up street
 	nf2 = split(ary[f_st], ary2, /  */)
 	if(nf2 < 2){
@@ -66,6 +92,7 @@
 	street = street ((ary2[nf2] in st_types) ? (" " st_types[ary2[nf2]]) : (" " ary2[nf2]))

 	result["status"] = "G"
+	result["name"] = name
 	result["street"] = street
 	result["town"] = town
 	result["state"] = "CA"


- syntax error

- syntax error

--- scripts/modpost.awk
+++ scripts/modpost.awk
@@ -2018,7 +2018,7 @@
 	    command = cat_command("/lib/modules/" kversion "/build/System.map")
 	    if (command) { read_systemmap(command, "vmlinux", "kernel", "systemmap") }
 	    else {
-	    print_error("r: systemmap, file not found") } } }
+	    print_error("r: systemmap, file not found") } } } }
 	}
 	if (("infile" in values) && values["infile"]) {
 	    command = cat_command(values["infile"])


fix quoting a bit

fix quoting a bit

--- tools/wiki2latex.awk
+++ tools/wiki2latex.awk
@@ -51,7 +51,7 @@

 ## pragmas do not count
-/\#labels/ {
+/^\#labels/ {
   next;
 }

@@ -59,6 +59,11 @@
 ## make sure that control sequences are always at the front
 / *=/ { sub(/ */, "") }

+quoting && /^ / {
+  sub(/^ /, "");
+  print;
+  next;
+}

 itemizing && !/^   *\*/ {
@@ -66,16 +71,13 @@
   itemizing = 0;
 }

-quoting && /^  / {
-  sub(/^  /, "");
-  print;
-  next;
-}

-
-quoting && !/^  / {
+## quoting stops when item appears
+## or not indented any more
+quoting && (/^   *\*/ || !/^ /) {
   print "\\end{quotation}";
+  print ""
   quoting = 0;
 }

@@ -120,10 +122,11 @@
 }

-/^  / {
+/^ / {
+  print ""
   print "\\begin{quotation}";
   quoting = 1;
-  sub(/^  /, "");
+  sub(/^ /, "");
   print;
   next;
 }


Script: do not upgrade myself

Script: do not upgrade myself

--- include/Script.awk
+++ include/Script.awk
@@ -43,25 +43,12 @@
 }

 # Upgrade script.
-function upgrade(    gitHead, i, newVersion, registry, tokens, trans) {
-    if (!ENVIRON["TRANS_ABSPATH"]) {
-        w("[ERROR] Not running from a single executable.")
-        gitHead = getGitHead()
-        if (gitHead)
-            w("        Please try to upgrade via git commands.")
-        else
-            w("        Please download the latest release from here:" RS \
-              "        https://github.com/soimort/translate-shell/releases")
-        ExitCode = 1
-        return
-    }
-
+function upgrade(    i, newVersion, registry, tokens) {
     RegistryIndex = "https://raw.githubusercontent.com/soimort/translate-shell/registry/index.trans"
-    TransExecutable = "http://www.soimort.org/translate-shell/trans"

     registry = curl(RegistryIndex)
     if (!registry) {
-        e("[ERROR] Upgrading failed.")
+        e("[ERROR] Failed to check for upgrade.")
         ExitCode = 1
         return
     }
@@ -71,13 +58,11 @@
         if (tokens[i] == ":translate-shell")
             newVersion = literal(tokens[i + 1])
     if (newerVersion(newVersion, Version)) {
-        trans = curl(TransExecutable)
-        if (trans) {
-            print "Successfully upgraded to " newVersion "." > STDERR
-            print trans > ENVIRON["TRANS_ABSPATH"]
-            exit 0
-        } else
-            e("[ERROR] Upgrading failed due to network errors.")
-    } else
-        e("[ERROR] Already up-to-date.")
+        w("Current version: \t" Version)
+        w("New version available: \t" newVersion)
+        w("Download from: \t" "http://www.soimort.org/translate-shell/trans")
+    } else {
+        w("Current version: \t" Version)
+        w("Already up-to-date.")
+    }
 }


tests/uid.awk: rewrite in a more maintainable style

Since the test is virtually a FSM, rewrite it as a FSM.

--- tests/uid.awk
+++ tests/uid.awk
@@ -1,51 +1,48 @@
 BEGIN {
-  ok = 0
+  r_uint = "(0|[1-9][0-9]*)"
+  regexp = "^getuid" suffix "\\(\\)[[:space:]]+= " r_uint "$"
+  expected = "getuid"
   fail = 0
-  r_uid = "(0|[1-9][0-9]*)"
-  r_getuid = "^getuid" suffix "\\(\\)[[:space:]]+= " r_uid "$"
-  r_setuid = "^/$"
-  r_getresuid = "^/$"
-  r_setreuid = "^/$"
-  r_setresuid = "^/$"
-  r_chown = "^/$"
-  s_last = "/"
 }

-ok == 1 {
+regexp == "" {
   fail = 1
   next
 }

-$0 == s_last {
-  ok = 1
-  next
-}
-
 {
-  if (match($0, r_getuid, a)) {
-    r_uid = a[1]
-    r_setuid = "^setuid" suffix "\\(" r_uid "\\)[[:space:]]+= 0$"
-    next
-  }
-  if (match($0, r_setuid)) {
-    r_getresuid = "^getresuid" suffix "\\(\\[" r_uid "\\], \\[" r_uid "\\], \\[" r_uid "\\]\\)[[:space:]]+= 0$"
-    next
-  }
-  if (match($0, r_getresuid)) {
-    r_setreuid = "^setreuid" suffix "\\(-1, -1\\)[[:space:]]+= 0$"
-    next
-  }
-  if (match($0, r_setreuid)) {
-    r_setresuid = "^setresuid" suffix "\\(-1, " r_uid ", -1\\)[[:space:]]+= 0$"
-    next
-  }
-  if (match($0, r_setresuid)) {
-    r_chown = "^chown" suffix "\\(\".\", -1, -1\\)[[:space:]]+= 0$"
-    next
-  }
-  if (match($0, r_chown)) {
-    s_last = "+++ exited with 0 +++"
-    next
+  if (match($0, regexp, a)) {
+    switch (expected) {
+      case "getuid":
+        uid = a[1]
+        expected = "setuid"
+        regexp = "^setuid" suffix "\\(" uid "\\)[[:space:]]+= 0$"
+        next
+      case "setuid":
+        expected = "getresuid"
+        regexp = "^getresuid" suffix "\\(\\[" uid "\\], \\[" uid "\\], \\[" uid "\\]\\)[[:space:]]+= 0$"
+        next
+      case "getresuid":
+        expected = "setreuid"
+        regexp = "^setreuid" suffix "\\(-1, -1\\)[[:space:]]+= 0$"
+        next
+      case "setreuid":
+        expected = "setresuid"
+        regexp = "^setresuid" suffix "\\(-1, " uid ", -1\\)[[:space:]]+= 0$"
+        next
+      case "setresuid":
+        expected = "chown"
+        regexp = "^chown" suffix "\\(\".\", -1, -1\\)[[:space:]]+= 0$"
+        next
+      case "chown":
+        expected = "the last line"
+        regexp = "^\\+\\+\\+ exited with 0 \\+\\+\\+$"
+        next
+      case "the last line":
+        expected = "nothing"
+        regexp = ""
+        next
+    }
   }
   next
 }
@@ -55,32 +52,8 @@
     print "Unexpected output after exit"
     exit 1
   }
-  if (ok)
+  if (regexp == "")
     exit 0
-  if (r_setuid == "^/$") {
-    print "getuid doesn't match"
-    exit 1
-  }
-  if (r_getresuid == "^/$") {
-    print "setuid doesn't match"
-    exit 1
-  }
-  if (r_setreuid == "^/$") {
-    print "getresuid doesn't match"
-    exit 1
-  }
-  if (r_setresuid == "^/$") {
-    print "setreuid doesn't match"
-    exit 1
-  }
-  if (r_chown == "^/$") {
-    print "setresuid doesn't match"
-    exit 1
-  }
-  if (s_last == "/") {
-    print "chown doesn't match"
-    exit 1
-  }
-  print "The last line doesn't match"
+  print "error: " expected " doesn't match"
   exit 1
 }


Removing unneeded files in repo

Removing unneeded files in repo

--- parse_metadata.awk
+++ parse_metadata.awk
@@ -1,287 +0,0 @@
-##  Script for parsing arxiv metadata.  Call with a catalog file
-##  that lists the bookids and file location (with _ for /) of the
-##  abstracts:
-##          awk -f parse_metadata.awk ../texts/catalog.txt
-##
-##  The code in the BEGIN statement sets up hashes for convenience.  "a"
-##  is used to make the date into proper datetime SQL format.  "b" is to
-##  translate the raw categories into ones that we will use in our database
-BEGIN{
-  a["Jan"] = "01";
-  a["Feb"] = "02";
-  a["Mar"] = "03";
-  a["Apr"] = "04";
-  a["May"] = "05";
-  a["Jun"] = "06";
-  a["Jul"] = "07";
-  a["Aug"] = "08";
-  a["Sep"] = "09";
-  a["Oct"] = "10";
-  a["Nov"] = "11";
-  a["Dec"] = "12";
-  OFS = "\t";
-  where=0;
-
-  b["acc-phys"]="physics"
-  b["adap-org"]="nlin"
-  b["alg-geom"]="math"
-  b["ao-sci"]="physics"
-  b["astro-ph"]="physics.astro-ph"
-  b["astro-ph.CO"]="physics.astro-ph"
-  b["astro-ph.EP"]="physics.astro-ph"
-  b["astro-ph.GA"]="physics.astro-ph"
-  b["astro-ph.HE"]="physics.astro-ph"
-  b["astro-ph.IM"]="physics.astro-ph"
-  b["astro-ph.SR"]="physics.astro-ph"
-  b["atom-ph"]="physics"
-  b["bayes-an"]="physics"
-  b["chao-dyn"]="nlin"
-  b["chem-ph"]="physics"
-  b["cmp-lg"]="cs"
-  b["comp-gas"]="nlin"
-  b["cond-mat"]="physics.cond-mat"
-  b["cond-mat.dis-nn"]="physics.cond-mat"
-  b["cond-mat.mes-hall"]="physics.cond-mat"
-  b["cond-mat.mtrl-sci"]="physics.cond-mat"
-  b["cond-mat.other"]="physics.cond-mat"
-  b["cond-mat.quant-gas"]="physics.cond-mat"
-  b["cond-mat.soft"]="physics.cond-mat"
-  b["cond-mat.stat-mech"]="physics.cond-mat"
-  b["cond-mat.str-el"]="physics.cond-mat"
-  b["cond-mat.supr-con"]="physics.cond-mat"
-  b["cs.AI"]="cs"
-  b["cs.AR"]="cs"
-  b["cs.CC"]="cs"
-  b["cs.CE"]="cs"
-  b["cs.CG"]="cs"
-  b["cs.CL"]="cs"
-  b["cs.CR"]="cs"
-  b["cs.CV"]="cs"
-  b["cs.CY"]="cs"
-  b["cs.DB"]="cs"
-  b["cs.DC"]="cs"
-  b["cs.DL"]="cs"
-  b["cs.DM"]="cs"
-  b["cs.DS"]="cs"
-  b["cs.ET"]="cs"
-  b["cs.FL"]="cs"
-  b["cs.GL"]="cs"
-  b["cs.GR"]="cs"
-  b["cs.GT"]="cs"
-  b["cs.HC"]="cs"
-  b["cs.IR"]="cs"
-  b["cs.IT"]="cs"
-  b["cs.LG"]="cs"
-  b["cs.LO"]="cs"
-  b["cs.MA"]="cs"
-  b["cs.MM"]="cs"
-  b["cs.MS"]="cs"
-  b["cs.NA"]="cs"
-  b["cs.NE"]="cs"
-  b["cs.NI"]="cs"
-  b["cs.OH"]="cs"
-  b["cs.OS"]="cs"
-  b["cs.PF"]="cs"
-  b["cs.PL"]="cs"
-  b["cs.RO"]="cs"
-  b["cs.SC"]="cs"
-  b["cs.SD"]="cs"
-  b["cs.SE"]="cs"
-  b["cs.SI"]="cs"
-  b["cs.SY"]="cs"
-  b["dg-ga"]="math"
-  b["funct-an"]="math"
-  b["gr-qc"]="physics.gr-qc"
-  b["hep-ex"]="physics.hep-ex"
-  b["hep-lat"]="physics.hep-lat"
-  b["hep-ph"]="physics.hep-ph"
-  b["hep-th"]="physics.hep-th"
-  b["math.AC"]="math"
-  b["math.AG"]="math"
-  b["math.AP"]="math"
-  b["math.AT"]="math"
-  b["math.CA"]="math"
-  b["math.CO"]="math"
-  b["math.CT"]="math"
-  b["math.CV"]="math"
-  b["math.DG"]="math"
-  b["math.DS"]="math"
-  b["math.FA"]="math"
-  b["math.GM"]="math"
-  b["math.GN"]="math"
-  b["math.GR"]="math"
-  b["math.GT"]="math"
-  b["math.HO"]="math"
-  b["math.IT"]="math"
-  b["math.KT"]="math"
-  b["math.LO"]="math"
-  b["math.MG"]="math"
-  b["math.MP"]="math"
-  b["math.NA"]="math"
-  b["math.NT"]="math"
-  b["math.OA"]="math"
-  b["math.OC"]="math"
-  b["math-ph"]="math.math-ph"
-  b["math.PR"]="math"
-  b["math.QA"]="math"
-  b["math.RA"]="math"
-  b["math.RT"]="math"
-  b["math.SG"]="math"
-  b["math.SP"]="math"
-  b["math.ST"]="math"
-  b["mtrl-th"]="physics.cond-mat"
-  b["nlin.AO"]="nlin"
-  b["nlin.CD"]="nlin"
-  b["nlin.CG"]="nlin"
-  b["nlin.PS"]="nlin"
-  b["nlin.SI"]="nlin"
-  b["nucl-ex"]="physics.nucl-ex"
-  b["nucl-th"]="physics.nucl-th"
-  b["patt-sol"]="nlin"
-  b["physics.acc-ph"]="physics"
-  b["physics.ao-ph"]="physics"
-  b["physics.atm-clus"]="physics"
-  b["physics.atom-ph"]="physics"
-  b["physics.bio-ph"]="physics"
-  b["physics.chem-ph"]="physics"
-  b["physics.class-ph"]="physics"
-  b["physics.comp-ph"]="physics"
-  b["physics.data-an"]="physics"
-  b["physics.ed-ph"]="physics"
-  b["physics.flu-dyn"]="physics"
-  b["physics.gen-ph"]="physics"
-  b["physics.geo-ph"]="physics"
-  b["physics.hist-ph"]="physics"
-  b["physics.ins-det"]="physics"
-  b["physics.med-ph"]="physics"
-  b["physics.optics"]="physics"
-  b["physics.plasm-ph"]="physics"
-  b["physics.pop-ph"]="physics"
-  b["physics.soc-ph"]="physics"
-  b["physics.space-ph"]="physics"
-  b["plasm-ph"]="physics"
-  b["q-alg"]="math"
-  b["q-bio.BM"]="q-bio"
-  b["q-bio.CB"]="q-bio"
-  b["q-bio.GN"]="q-bio"
-  b["q-bio.MN"]="q-bio"
-  b["q-bio.NC"]="q-bio"
-  b["q-bio.OT"]="q-bio"
-  b["q-bio.PE"]="q-bio"
-  b["q-bio.QM"]="q-bio"
-  b["q-bio"]="q-bio"
-  b["q-bio.SC"]="q-bio"
-  b["q-bio.TO"]="q-bio"
-  b["q-fin.CP"]="q-fin"
-  b["q-fin.GN"]="q-fin"
-  b["q-fin.PM"]="q-fin"
-  b["q-fin.PR"]="q-fin"
-  b["q-fin.RM"]="q-fin"
-  b["q-fin.ST"]="q-fin"
-  b["q-fin.TR"]="q-fin"
-  b["quant-ph"]="physics.quant-ph"
-  b["solv-int"]="nlin"
-  b["stat.AP"]="stat"
-  b["stat.CO"]="stat"
-  b["stat.ME"]="stat"
-  b["stat.ML"]="stat"
-  b["stat.OT"]="stat"
-  b["stat.TH"]="stat"
-  b["supr-con"]="physics.cond-mat"
-}
-{
-  # x is the book id
-  x = $1;
-
-  # fn is the filename
-  fn = $2;
-  gsub(/_/,"/", fn);
-  fn = "../abs/"fn".abs"
-
-  # where is used to deal with multiline author and title fields
-  # t is title, au is author, c is the categories, fields is the line
-  # we read in
-  where = 0;
-  t = "";
-  au = "";
-  delete c;
-  delete fields;
-  while ((getline line < fn) > 0) {
-    len=split(line, fields);
-    # arxiv id
-    if (line ~ /^arXiv:/) {
-      id=substr(line,7);
-    }
-    # email address
-    if (line ~ /^From:/) {
-      from=substr(line,7);
-      # take only the email address, not user name
-      st=index(from, "<");
-      ed=index(from, ">");
-      from2=substr(from,st+1,ed-st-1);
-      # take only the domain from the email address
-      at=index(from2, "@");
-      from=substr(from2, at+1);
-      num=split(from, s, "\\.");
-      final=s[num];
-      # write out the domain levels separated by tabs.
-      # the first level is "edu", then "harvard.edu", then "seas.harvard.edu"
-      for (i=num-1; i>=1; i--) {
-        dl=sprintf("%s", s[i]);
-        for (j=i+1; j<=num; j++) {
-	  dl=sprintf("%s.%s", dl,s[j]);
-        }
-        final=sprintf("%s\t%s",final,dl);
-      }
-    }
-    # date, convert to datetime format
-    if (line ~ /^Date:/) {
-      ds=sprintf("%s-%s-%02d %s",fields[5],a[fields[4]],fields[3],fields[6])
-    }
-    # where is for dealing with multiline title
-    if (line ~ /^Title:/) {
-      t=substr(line, index(line,fields[2]));
-      where=1;
-    }
-    # where is for dealing with multiline author
-    if (line ~ /^Authors:/) {
-      au=substr(line, index(line,fields[2]));
-      where=2;
-    }
-    # if line starts with an indentation, choose appropriate field to add to
-    if (line ~ /^  /) {
-      if (where==1)
-	t=t""line;
-      else if (where==2)
-	au=au""line;
-    }
-    # reset where if we get to end of metadata
-    if (line ~ /^\\/) {
-      where=0;
-    }
-    # reset where if we get to Categories, which is always after title/author
-    if (line ~ /^Categories:/) {
-      where = 0;
-      # loop over all categories
-      for (i=2; i<=len; i++) {
-	# check if we already saw it; want to preserve original order
-        if (!(fields[i] in c)) {
-	  # check if it's a funky one
-	  if (fields[i] in b) {
-	    # b-mapped category not seen yet, add
-	    if (!(b[fields[i]] in c)) {
-	      c[b[fields[i]]]=i;
-	      print x,id,ds,t,au,b[fields[i]], final;
-	    }
-	  }
-	  else {
-	    # regular category not seen yet, add
-	    c[fields[i]] = i;
-	    print x,id,ds,t,au,fields[i], final;
-	  }
-	}
-      }
-    }
-  }
-  close (fn);
-}


render code blocks at EOF - CTR

render code blocks at EOF - CTR

--- docs/preprocessor/awk/tabify.awk
+++ docs/preprocessor/awk/tabify.awk
@@ -126,3 +126,10 @@
     else code = code "\n" $0
   }
 }
+
+END {
+  # EOF
+  if (status == 3) {
+    print_tabs(next_id, tabs, blocks)
+  }
+}


second

second

--- demon-lin-wm-auto.awk
+++ demon-lin-wm-auto.awk
@@ -39,24 +39,14 @@
   while ((C = getopt(ARGC, ARGV, "d:p:")) != -1) {
     if(C == "p")                                     # -p <project>      Project to run
       pid = verifypid(Optarg)
-    if(C == "d")                                     # -d <number>       Delay seconds to use (must be > 12). If set, no random delay.
-      delay = Optarg                                 #                     If -d not set, a random delay period is used (15 + 1-50 seconds)
-                                                     #                     If -d0 (zero), no delay
+    if(C == "d")                                     # -d <number>       Delay seconds to use.
+      delay = Optarg                                 #                     If -d0 (zero), no delay
   }
   setProject(pid)     # library.awk .. load Project[] paths via project.cfg
                       # if -p not given, use default noted in project.cfg

-  if( delay == "" || (delay < 12 && delay > 0) || ! isanumber(delay) ) {
-    delay = 15
-    delayrandom = 1
-  }
-  else if(delay == 0) {
+  if(delay == "" || ! isanumber(delay) ) {
     delay = 0
-    delayrandom = 0
-  }
-  else {
-    delay = 15
-    delayrandom = 0
   }

   main()
@@ -119,10 +109,7 @@
                 if(checkexists(tempid "article.waybackmedic.txt") ) {
                   command = Exe["cp"] " " tempid "article.waybackmedic.txt " Ramdisk "article.txt"
                   prnt("demon-lin.awk: Status successful. Copying article.waybackmedic.txt to shared directory. " name)
-                  if(delayrandom)
-                    sleep( delay + randomnumber(40) ) # 180 will do ~300 in ~ 9 hours
-                  else
-                    sleep( delay )
+                  sleep( delay )
                   sys2var(command)
                 }
                 else {


layerman: fix typo in text output

layerman: fix typo in text output

Signed-off-by: Koen Kooi <42e3d96910f922bdd7dd1805fe3f8aff634f391d@dominion.thruhere.net>

--- scripts/layers.awk
+++ scripts/layers.awk
@@ -4,6 +4,6 @@
 	print "Configured layers:\n";
  }

-$1 != "# Name" { print "layer repository nam/e: " $1 "\nlayer uri: " $2 "\nlayer branch/revision: " $3 "/" $4 ; system("${OE_BASE}/scripts/layerman " $1 " "  $2 " " $3 " " $4 " " command " " commandarg);}
+$1 != "# Name" { print "layer repository name: " $1 "\nlayer uri: " $2 "\nlayer branch/revision: " $3 "/" $4 ; system("${OE_BASE}/scripts/layerman " $1 " "  $2 " " $3 " " $4 " " command " " commandarg);}


MONDRIAN: Integrate from latest util/bin/checkFile.awk.

[git-p4: depot-paths = "//open/mondrian/": change = 14186]

--- bin/checkFile.awk
+++ bin/checkFile.awk
@@ -12,6 +12,7 @@
        || fname ~ "/aspen/" \
        || fname ~ "/farrago/" \
        || fname ~ "/fennel/" \
+       || fname ~ "/extensions/" \
        || fname ~ "/com/sqlstream/" \
        || !lenient;
 }
@@ -30,6 +31,43 @@
     delete switchStack[switchStackLen];
     return val;
 }
+function afterFile() {
+    # Compute basename. If fname="/foo/bar/baz.txt" then basename="baz.txt".
+    basename = fname;
+    gsub(".*/", "", basename);
+    gsub(lf, "", lastNonEmptyLine);
+    terminator = "// End " basename;
+    if (matchFile && (lastNonEmptyLine != terminator)) {
+        error(fname, FNR, sprintf("Last line should be %c%s%c", 39, terminator, 39));
+    }
+}
+# Returns whether there are unmatched open parentheses.
+# unmatchedOpenParens("if ()") returns false.
+# unmatchedOpenParens("if (") returns true.
+# unmatchedOpenParens("if (foo) bar(") returns false
+function unmatchedOpenParens(s) {
+    i = index(s, "(");
+    if (i == 0) {
+    if (0)         print FNR, "unmatchedOpenParens=0";
+        return 0;
+    }
+    openCount = 1;
+    while (++i <= length(s)) {
+        c = substr(s, i, 1);
+        if (c == "(") {
+            ++openCount;
+        }
+        if (c == ")") {
+            if (--openCount == 0) {
+    if (0)         print FNR, "unmatchedOpenParens=0 (b)";
+                return 0;
+            }
+        }
+    }
+    if (0) print FNR, "unmatchedOpenParens=1";
+    return 1;
+}
+
 BEGIN {
     # pre-compute regexp for quotes, linefeed
     apos = sprintf("%c", 39);
@@ -39,6 +77,9 @@
     if (0) printf "maxLineLength=%s lenient=%s\n", maxLineLength, lenient;
 }
 FNR == 1 {
+    if (fname) {
+        afterFile();
+    }
     fname = FILENAME;
     matchFile = _matchFile(fname);
     isCpp = _isCpp(fname);
@@ -114,6 +155,9 @@
         error(fname, FNR, "Carriage return character (file is in DOS format?)");
     }
 }
+/./ {
+    lastNonEmptyLine = $0;
+}
 {
     # Rules beyond this point only apply to Java and C++.
     if (!isCpp && !isJava) {
@@ -165,7 +209,7 @@
         error(fname, FNR, "for/switch/synchronized/catch must be followed by space");
     }
 }
-s ~ /\<(if|while|for|switch)\>/ {
+s ~ /\<(if|while|for|switch|catch)\>/ {
     # Check single-line if statements, such as
     #   if (condition) return;
     # We recognize such statements because there are equal numbers of open and
@@ -186,11 +230,11 @@
     } else if (s ~ /if \(true|false\)/) {
         # allow "if (true)" and "if (false)" because they are
         # used for commenting
-    } else if (length(opens) == length(closes)  \
-               && length($0) != 79              \
+    } else if (!unmatchedOpenParens(s)  \
+               && length($0) != 79      \
                && length($0) != 80)
     {
-        error(fname, FNR, "single-line if/while/for/switch must end in {");
+        error(fname, FNR, "single-line if/while/for/switch/catch must end in {");
     }
 }
 s ~ /[[:alnum:]]\(/ &&
@@ -518,9 +562,6 @@
         FNR, \
         "Line length (" length($0) ") exceeds " maxLineLength " chars");
 }
-/./ {
-    lastNonEmptyLine = $0;
-}
 /}$/ {
     previousLineEndedInCloseBrace = 2;
 }
@@ -556,14 +597,7 @@
     next;
 }
 END {
-    # Compute basename. If fname="/foo/bar/baz.txt" then basename="baz.txt".
-    basename = fname;
-    gsub(".*/", "", basename);
-    gsub(lf, "", lastNonEmptyLine);
-    terminator = "// End " basename;
-    if (matchFile && (lastNonEmptyLine != terminator)) {
-        error(fname, FNR, sprintf("Last line should be %c%s%c", 39, terminator, 39));
-    }
+    afterFile();
 }

 # End checkFile.awk


First working version of parser

First working version of parser

--- getFullcastFrom-imdb.awk
+++ getFullcastFrom-imdb.awk
@@ -1,5 +1,6 @@
 BEGIN {
     FS = "\t"
+    printf ("Title\tPerson\tType\tRole\tEpisodes\tYears\n")
 }

 {
@@ -33,6 +34,8 @@
         nflds1 = split (Cast,fld,/[[:blank:]]{3,99}/)
         person = fld[1]
         role = fld[3]
+        if (role ~ /^'/)
+            role = "'" role
         sub (/\302\240/,"",role)
         episodes = fld[4]
         if (episodes !~ /episodes?/) {
@@ -85,6 +88,7 @@
         }
     }

-    printf ("%s %s\t%s\t%s\t%s\t%s\t%s\n",Title,Years,person,type,role,num_episodes,episode_years)
+    printf ("=HYPERLINK(\"%s\";\"%s %s\"\)\t%s\t%s\t%s\t%s\t%s\n",web_scraper_start_url,Title,Years,person,type,role,\
+                num_episodes,episode_years)

 }


interp_utils.awk	-- reordered to put visible funcs first; also added '_' pfx to funcs that are not to be used directly

--- lib/interp_utils.awk
+++ lib/interp_utils.awk
@@ -31,9 +31,9 @@
 		if(index(ary[i], ":") != 0){
 			interp["is_grad"] = 1
 			v_pat = v_pat "g"
-			v_len = IU_check_grad(ary[i])
+			v_len = _IU_check_grad(ary[i])
 			if(v_len == 0){
-				printf("ERROR: IU_init: IU_check_grad failed for value %d (%s)\n", i, ary[i]) > "/dev/stderr"
+				printf("ERROR: IU_init: _IU_check_grad failed for value %d (%s)\n", i, ary[i]) > "/dev/stderr"
 				return 1
 			}else if(interp["v_len"] == 0){
 				interp["v_len"] = v_len
@@ -101,7 +101,7 @@
 	key = name ".exceptions"
 	work = config["_globals", key]
 	if(work != ""){
-		if(IU_parse_exceptions(interp, work))
+		if(_IU_parse_exceptions(interp, work))
 			return 1
 	}

@@ -113,81 +113,60 @@
 	return 0
 }

-function IU_check_grad(grad,   v_len, n_ary, ary, i, n_ary2, ary2, j) {
-
-	v_len = 0
-	n_ary = split(grad, ary, ":")
-	if(n_ary != 2){
-		printf("ERROR: IU_check_grad: grad %s has %d fields, must have %d\n", grad, n_ary, 2) > "/dev/stderr"
-		return 0
-	}
-	for(i = 1; i <= n_ary; i++){
-		n_ary2 = split(ary[i], ary2, ",")
-		if(v_len == 0)
-			v_len = n_ary2
-		else if(n_ary2 != v_len){
-			printf("ERROR: IU_check_grad: vector %s has %d elements, must have %d\n", ary[i], n_ary2, v_len) > "/dev/stderr"
-			return 0
-		}
-	}
-
-	return v_len
-}
-
-function IU_parse_exceptions(interp, str,   err, n_ary, ary, i, colon, cond, op, opnd, value) {
-
-	err = 0
-	interp["exceptions"] = str
-	n_ary = split(str, ary, "|")
-	for(i = 1; i <= n_ary; i++){
-		sub(/^  */, "", ary[i])
-		sub(/  *$/, "", ary[i])
-	}
-	interp["nexceptions"] = n_ary
-	for(i = 1; i <= n_ary; i++){
-		colon = index(ary[i], ":")
-		if(colon == 0){
-			printf("ERROR: IU_parse_exception: no colon: %s\n", ary[i]) > "/dev/stderr"
-			return 1
-		}
-		cond = substr(ary[i], 1, colon - 1)
-		sub(/^  */, "", cond)
-		sub(/  *$/, "", cond)
-		if(cond == ""){
-			printf("ERROR: IU_parse_exception: empty condition: %s\n", ary[i]) > "/dev/stderr"
-			return 1
-		}
-		# op can be <=, <, ==, !=, >=, >
-		op = substr(cond, 1, 2)
-		if(op == "<=" || op == "==" || op == "!=" || op == ">="){
-			opnd = substr(cond, 3)
-		}else{
-			op = substr(op, 1, 1)
-			if(op == "<" || op == ">")
-				opnd = substr(cond, 2)
-			else{
-				printf("ERROR: IU_parse_exception: unknown operator \"%s\"\n", cond) > "/dev/stderr"
-				return 1
-			}
-		}
-		sub(/^  */, "", opnd)
-		sub(/  *$/, "", opnd)
-		if(cond == ""){
-			print("ERROR: IU_parse_exception: exception %d: %s: empty operand %s\n", i, ary[i]) > "/dev/stderr"
-			return 1
-		}
-
-		value = substr(ary[i], colon + 1)
-		sub(/^  */, "", value)
-		sub(/  *$/, "", value)
-		# TODO? value can be empty, is this OK?
-
-		interp["exceptions", i, "op"] = op
-		interp["exceptions", i, "opnd"] = opnd + 0 # force numeric
-		interp["exceptions", i, "value"] = value
-		interp["ecounts", i] = 0
-	}
-	return err
+function IU_interpolate(interp, v,   ev, idx, work, n_ary, ary, i) {
+
+	if("exceptions" in interp){
+		ev = _IU_handle_exceptions(interp, v)
+		if(ev != "")
+			return ev
+	}else if(interp["scale_type"] == "log"){
+		if(v <= 0)
+			return ""
+	}
+
+	idx = _IU_search(interp, v)
+	interp["tcounts"]++
+	interp["counts", idx]++
+	if(!interp["is_grad"]){
+		return interp["values", idx]
+	}else{
+		# nbreaks = nvalues - 1
+		if(interp["v_ob_info"]  == ""){	# ^gg*$, take out of bounds values from first and last grad elemnt
+			if(idx == 1){
+				work = interp["values", 1]
+				n_ary = split(work, ary, ":")
+				return ary[1]
+			}else if(idx == interp["nbreaks"] + 1){
+				work = interp["values", interp["nvalues"]]
+				n_ary = split(work, ary, ":")
+				return ary[2]
+			}else
+				return _IU_interpolate_grad(interp, interp["values", idx - 1], v, interp["breaks", idx - 1], interp["breaks", idx])
+		}else if(interp["v_ob_info"] == "^"){	# ^bgg*$, lower out of bounds specified, take higher ob from last grad element
+			if(idx == 1)
+				return interp["values", 1]
+			else if(idx == interp["nbreaks"] + 1){
+				work = interp["values", interp["nvalues"]]
+				n_ary = split(work, ary, ":")
+				return ary[2]
+			}else
+				return _IU_interpolate_grad(interp, interp["values", idx], v, interp["breaks", idx], interp["breaks", idx + 1])
+		}else if(interp["v_ob_info"] == "$"){	# ^gg*b$, upper out of bounds specified, take lower ob from first grad element
+			if(idx == 1){
+				work = interp["values", 1]
+				n_ary = split(work, ary, ":")
+				return ary[1]
+			}else if(idx == interp["nbreaks"] + 1)
+				return interp["values", idx - 1]
+			else
+				return _IU_interpolate_grad(interp, interp["values", idx - 1], v, interp["breaks", idx - 1], interp["breaks", idx])
+		}else{	# ^bgg*b$, lower & upper ob info specified
+			if(idx == 1 || idx == interp["nbreaks"] + 1)
+				return interp["values", idx]
+			else
+				return _IU_interpolate_grad(interp, interp["values", idx], v, interp["breaks", idx], interp["breaks", idx + 1])
+		}
+	}
 }

 function IU_dump(file, interp,   i, keys, nk) {
@@ -229,63 +208,84 @@
 	printf("}\n") > file
 }

-function IU_interpolate(interp, v,   ev, idx, work, n_ary, ary, i) {
-
-	if("exceptions" in interp){
-		ev = IU_handle_exceptions(interp, v)
-		if(ev != "")
-			return ev
-	}else if(interp["scale_type"] == "log"){
-		if(v <= 0)
-			return ""
-	}
-
-	idx = IU_search(interp, v)
-	interp["tcounts"]++
-	interp["counts", idx]++
-	if(!interp["is_grad"]){
-		return interp["values", idx]
-	}else{
-		# nbreaks = nvalues - 1
-		if(interp["v_ob_info"]  == ""){	# ^gg*$, take out of bounds values from first and last grad elemnt
-			if(idx == 1){
-				work = interp["values", 1]
-				n_ary = split(work, ary, ":")
-				return ary[1]
-			}else if(idx == interp["nbreaks"] + 1){
-				work = interp["values", interp["nvalues"]]
-				n_ary = split(work, ary, ":")
-				return ary[2]
-			}else
-				return IU_interpolate_grad(interp, interp["values", idx - 1], v, interp["breaks", idx - 1], interp["breaks", idx])
-		}else if(interp["v_ob_info"] == "^"){	# ^bgg*$, lower out of bounds specified, take higher ob from last grad element
-			if(idx == 1)
-				return interp["values", 1]
-			else if(idx == interp["nbreaks"] + 1){
-				work = interp["values", interp["nvalues"]]
-				n_ary = split(work, ary, ":")
-				return ary[2]
-			}else
-				return IU_interpolate_grad(interp, interp["values", idx], v, interp["breaks", idx], interp["breaks", idx + 1])
-		}else if(interp["v_ob_info"] == "$"){	# ^gg*b$, upper out of bounds specified, take lower ob from first grad element
-			if(idx == 1){
-				work = interp["values", 1]
-				n_ary = split(work, ary, ":")
-				return ary[1]
-			}else if(idx == interp["nbreaks"] + 1)
-				return interp["values", idx - 1]
-			else
-				return IU_interpolate_grad(interp, interp["values", idx - 1], v, interp["breaks", idx - 1], interp["breaks", idx])
-		}else{	# ^bgg*b$, lower & upper ob info specified
-			if(idx == 1 || idx == interp["nbreaks"] + 1)
-				return interp["values", idx]
-			else
-				return IU_interpolate_grad(interp, interp["values", idx], v, interp["breaks", idx], interp["breaks", idx + 1])
-		}
-	}
-}
-
-function IU_handle_exceptions(interp, v,   i, hit) {
+function _IU_check_grad(grad,   v_len, n_ary, ary, i, n_ary2, ary2, j) {
+
+	v_len = 0
+	n_ary = split(grad, ary, ":")
+	if(n_ary != 2){
+		printf("ERROR: _IU_check_grad: grad %s has %d fields, must have %d\n", grad, n_ary, 2) > "/dev/stderr"
+		return 0
+	}
+	for(i = 1; i <= n_ary; i++){
+		n_ary2 = split(ary[i], ary2, ",")
+		if(v_len == 0)
+			v_len = n_ary2
+		else if(n_ary2 != v_len){
+			printf("ERROR: _IU_check_grad: vector %s has %d elements, must have %d\n", ary[i], n_ary2, v_len) > "/dev/stderr"
+			return 0
+		}
+	}
+
+	return v_len
+}
+
+function _IU_parse_exceptions(interp, str,   err, n_ary, ary, i, colon, cond, op, opnd, value) {
+
+	err = 0
+	interp["exceptions"] = str
+	n_ary = split(str, ary, "|")
+	for(i = 1; i <= n_ary; i++){
+		sub(/^  */, "", ary[i])
+		sub(/  *$/, "", ary[i])
+	}
+	interp["nexceptions"] = n_ary
+	for(i = 1; i <= n_ary; i++){
+		colon = index(ary[i], ":")
+		if(colon == 0){
+			printf("ERROR: _IU_parse_exception: no colon: %s\n", ary[i]) > "/dev/stderr"
+			return 1
+		}
+		cond = substr(ary[i], 1, colon - 1)
+		sub(/^  */, "", cond)
+		sub(/  *$/, "", cond)
+		if(cond == ""){
+			printf("ERROR: _IU_parse_exception: empty condition: %s\n", ary[i]) > "/dev/stderr"
+			return 1
+		}
+		# op can be <=, <, ==, !=, >=, >
+		op = substr(cond, 1, 2)
+		if(op == "<=" || op == "==" || op == "!=" || op == ">="){
+			opnd = substr(cond, 3)
+		}else{
+			op = substr(op, 1, 1)
+			if(op == "<" || op == ">")
+				opnd = substr(cond, 2)
+			else{
+				printf("ERROR: _IU_parse_exception: unknown operator \"%s\"\n", cond) > "/dev/stderr"
+				return 1
+			}
+		}
+		sub(/^  */, "", opnd)
+		sub(/  *$/, "", opnd)
+		if(cond == ""){
+			print("ERROR: _IU_parse_exception: exception %d: %s: empty operand %s\n", i, ary[i]) > "/dev/stderr"
+			return 1
+		}
+
+		value = substr(ary[i], colon + 1)
+		sub(/^  */, "", value)
+		sub(/  *$/, "", value)
+		# TODO? value can be empty, is this OK?
+
+		interp["exceptions", i, "op"] = op
+		interp["exceptions", i, "opnd"] = opnd + 0 # force numeric
+		interp["exceptions", i, "value"] = value
+		interp["ecounts", i] = 0
+	}
+	return err
+}
+
+function _IU_handle_exceptions(interp, v,   i, hit) {

 	for(i = 1; i <= interp["nexceptions"]; i++){
 		hit = ""
@@ -316,34 +316,7 @@
 	return ""
 }

-function IU_interpolate_grad(interp, grad, v, v_min, v_max,   n_ary, ary, n_ary2, ary2, i, g_min, g_max, f, rstr) {
-
-	# grad is well formed or IU_init() would have failed
-	n_ary = split(grad, ary, ":")
-	n_ary2 = split(ary[1], ary2, ",")
-	for(i = 1; i <= n_ary2; i++)
-		g_min[i] = ary2[i] + 0	# force numeric
-	n_ary2 = split(ary[2], ary2, ",")
-	for(i = 1; i <= n_ary2; i++)
-		g_max[i] = ary2[i] + 0	# force numeric
-
-	# other scales may be possible but for now
-	if(interp["scale_type"] == "log"){
-		log10 = log(10)
-		v = log(v)/log10
-		v_min = log(v_min)/log10
-		v_max = log(v_max)/log10
-	}
-
-	f = (v - v_min) / (v_max - v_min)	# safe b/c IU_init() checked that v_max > v_min
-	rstr = ""
-	for(i = 1; i <= n_ary2; i++){
-		rstr = rstr ((i > 1) ? "," : "") sprintf("%g", g_min[i] + f * (g_max[i] - g_min[i]))
-	}
-	return rstr
-}
-
-function IU_search(interp, v,   i, j, k, cv) {
+function _IU_search(interp, v,   i, j, k, cv) {

 	# deal with out of range values here to simplify the binary interval search
 	if(v <= interp["breaks", 1])
@@ -370,3 +343,30 @@
 	# should never get here!
 	return 0
 }
+
+function _IU_interpolate_grad(interp, grad, v, v_min, v_max,   n_ary, ary, n_ary2, ary2, i, g_min, g_max, f, rstr) {
+
+	# grad is well formed or IU_init() would have failed
+	n_ary = split(grad, ary, ":")
+	n_ary2 = split(ary[1], ary2, ",")
+	for(i = 1; i <= n_ary2; i++)
+		g_min[i] = ary2[i] + 0	# force numeric
+	n_ary2 = split(ary[2], ary2, ",")
+	for(i = 1; i <= n_ary2; i++)
+		g_max[i] = ary2[i] + 0	# force numeric
+
+	# other scales may be possible but for now
+	if(interp["scale_type"] == "log"){
+		log10 = log(10)
+		v = log(v)/log10
+		v_min = log(v_min)/log10
+		v_max = log(v_max)/log10
+	}
+
+	f = (v - v_min) / (v_max - v_min)	# safe b/c IU_init() checked that v_max > v_min
+	rstr = ""
+	for(i = 1; i <= n_ary2; i++){
+		rstr = rstr ((i > 1) ? "," : "") sprintf("%g", g_min[i] + f * (g_max[i] - g_min[i]))
+	}
+	return rstr
+}