bundle example in template maker

bundle example in template maker

# header2params2.sh
#
# new version of headers2params.sh, processing by line instead of parsing the first line.
#
# Used by $CSV2RDF4LOD_HOME/bin/convert.sh
#
# Parameters:
# -v surrogate
# -v sourceID
# -v datasetID
# -v datasetVersion
# -v subjectDiscriminator
# -v conversionID
#
# -v cellDelimiter
# -v header
# -v dataStart
# -v dataEnd
#
# -v onlyIfCol
# -v repeatAboveIfEmptyCol
# -v interpretAsNull
#
# -v whoami
# -v machine_uri
# -v person_uri

BEGIN {
   ALWAYS_SHOW_CONVERSION_PROCESS = 1; # Added back in to gather empirical results quantifying "effort" to create e1 params.
   showConversionProcess = ALWAYS_SHOW_CONVERSION_PROCESS + length(conversionID) + length(subjectDiscriminator) + length(header) + length(dataStart) + length(interpretAsNull) + length(dataEnd);
   #FS=","
   STEP = length(conversionID) ? sprintf("enhancement/%s",conversionID) : "raw";
   TYPE = length(conversionID) ? "Enhancement" : "Raw";
   # TODO: '|' has no length? --\/
          DELIMTER  = length(cellDelimiter) ? cellDelimiter : "	" # <--- that's a tab character.
   commentDELIMITER = length(cellDelimiter) ? ""            : "#";
   #print "#AWK: cellDelimiter:",cellDelimiter," DELIMITER: ",DELIMITER," comment: ",commentDELIMITER

   if(length(showConversionProcess)) {
      print "@prefix rdf:           <http://www.w3.org/1999/02/22-rdf-syntax-ns#> ."
      print "@prefix rdfs:          <http://www.w3.org/2000/01/rdf-schema#> ."
   }
   RDFS="rdfs"
   if(length(conversionID)) {
      print "@prefix todo:          <http://www.w3.org/2000/01/rdf-schema#> ."
      RDFS="todo"
   }
   print "@prefix xsd:        <http://www.w3.org/2001/XMLSchema#> ."
   if(length(conversionID)) {
      print "@prefix owl:           <http://www.w3.org/2002/07/owl#> ."
      print "@prefix vann:          <http://purl.org/vocab/vann/> ."
      print "@prefix skos:          <http://www.w3.org/2004/02/skos/core#> ."
      print "@prefix time:          <http://www.w3.org/2006/time#> ."
      print "@prefix wgs:           <http://www.w3.org/2003/01/geo/wgs84_pos#> ."
      print "@prefix geonames:      <http://www.geonames.org/ontology#> ."
      print "@prefix geonamesid:    <http://sws.geonames.org/> ."
      print "@prefix govtrackusgov: <http://www.rdfabout.com/rdf/usgov/geo/us/> ."
      print "@prefix dbpedia:       <http://dbpedia.org/resource/> ."
      print "@prefix con:           <http://www.w3.org/2000/10/swap/pim/contact#> ."
      print "@prefix muo:           <http://purl.oclc.org/NET/muo/muo#> ."
   }
   print "@prefix dcterms:       <http://purl.org/dc/terms/> ."
   print "@prefix void:          <http://rdfs.org/ns/void#> ."
   print "@prefix scovo:         <http://purl.org/NET/scovo#> ."
   print "@prefix sioc:          <http://rdfs.org/sioc/ns#> ."
   print "@prefix foaf:          <http://xmlns.com/foaf/0.1/> ."
   print "@prefix ov:            <http://open.vocab.org/terms/> ."
   print "@prefix conversion:    <http://purl.org/twc/vocab/conversion/> ."

   # Converter produces URIs for the LayerDatasets:
   #
   # <http://logd.tw.rpi.edu/source/nitrd-gov/dataset/fedRDnetIT/version/2011-Jan-27/conversion/raw>
   # <http://logd.tw.rpi.edu/source/nitrd-gov/dataset/fedRDnetIT/version/2011-Jan-27/conversion/enhancement/1>
   #
   # To make the params more connected to the datasets, we're replacing this:
   #### NOTE: brought this back for a place for implicit bundles to be named, HOWEVER, the dataset is NOT being named within this:
   printf("@prefix :              <%s/source/%s/dataset/%s/version/%s/params/%s/> .\n",surrogate,sourceID,datasetID,datasetVersion,STEP);
   # with this:
   # Still not right; moved down to subject:
   #printf("@prefix :           <%s/source/%s/dataset/%s/version/%s/conversion/%s> .\n",surrogate,sourceID,datasetID,datasetVersion,STEP);

   #
   # Describe the creator.
   #
   # NOTE: user account and person implemented in bin/util/user-account.sh, too.
                                     print
   if( length(machine_uri) && length(whoami) ) {
      if(length(person_uri)) {
                                    printf("<%s> foaf:holdsAccount <%s%s> .\n",person_uri,   machine_uri,whoami);
      }
                                    printf("<%s%s>\n   a foaf:OnlineAccount;\n   foaf:accountName \"%s\";\n",machine_uri,whoami,   whoami);
                                    printf("   dcterms:isPartOf <%s>;\n",machine_uri);
      if(length(person_uri)) {
                                    printf("   sioc:account_of  <%s>;\n",person_uri);
      }
                                    printf(".\n");
   }else if(length(person_uri)&&length(whoami)) {
                                    printf("<%s> dcterms:identifier \"%s\" .\n",person_uri,whoami);
   }

   if( length(conversionID)) {
                                    printf(":a_bundle\n");
                                    printf("   conversion:property_name \"a_property\"; # Can also be a URI, e.g. dcterms:title.\n");
                                    printf("   conversion:type_name     \"My Class\";   # Can also be a URI, e.g. foaf:Person.\n");
                                    printf(".");
   }
   #
   # Describe the dataset.
   #
                                     print
                                    printf("<%s/source/%s/dataset/%s/version/%s/conversion/%s>\n",surrogate,sourceID,datasetID,datasetVersion,STEP);
                                     print "   a conversion:LayerDataset, void:Dataset;\n"
                                    printf("   conversion:base_uri           \"%s\"^^xsd:anyURI;\n",surrogate);
                                    printf("   conversion:source_identifier  \"%s\";\n",sourceID);
                                    printf("   conversion:dataset_identifier \"%s\";\n",datasetID);
                                    printf("   conversion:version_identifier \"%s\";\n",datasetVersion);
                                    #printf("   conversion:dataset_version    \"%s\"; # DEPRECATED in favor of version_identifier\n",datasetVersion);
                                     print ""
                                     print "   conversion:conversion_process ["
                                    printf("      a conversion:%sConversionProcess;\n",TYPE);
   if(!length(conversionID))        printf("      conversion:conversion_identifier \"raw\";\n");
   if( length(conversionID))        printf("      conversion:enhancement_identifier \"%s\";\n",conversionID);
   if(length(subjectDiscriminator)) printf("      conversion:subject_discriminator  \"%s\";\n",subjectDiscriminator);

   #
   # Authorship description.
   #
                                     print
   if(length(machine_uri) && length(whoami)) {
                                    printf("      dcterms:creator <%s%s>;\n",machine_uri,whoami); # NOTE: implemented in bin/util/user-account.sh, too.
   }else if(length(person_uri) && length(whoami)) {
                                    printf("      dcterms:creator [ a foaf:OnlineAccount; foaf:accountName \"%s\";\n",whoami);
                                    printf("                        sioc:account_of <%s> ];\n",person_uri);
   }else if(length(whoami)) {
                                    printf("      dcterms:creator [ a foaf:OnlineAccount; foaf:accountName \"%s\" ];\n",whoami);
   }
   if(length(nowXSD)) {
                                    printf("      dcterms:created \"%s\"^^xsd:dateTime;\n\n",nowXSD);
   }

   #
   # Structural enhancement parameters.
   #
                                    printf("      conversion:delimits_cell \"%s\";\n",cellDelimiter);
                                    printf("      #conversion:delimits_cell \"	\"; # tab\n");
                                    printf("      #conversion:delimits_cell \"|\";   # pipe\n");
                                    printf("      #conversion:delimits_cell \",\";   # comma\n");
                                    print
   if(length(header)) {
                                    # Include header info even if just raw.
                                    printf("      conversion:enhance [      \n");
                                    printf("         ov:csvRow %s;\n",header);
                                    printf("         a conversion:HeaderRow;\n");
                                    printf("      ];                        \n");
   }
   if(length(dataStart)) {
                                    printf("      conversion:enhance [          \n");
                                    printf("         ov:csvRow %s;\n",dataStart);
                                    printf("         a conversion:DataStartRow; \n");
                                    printf("      ];                            \n");
   }
   comment_out = length(interpretAsNull) && length(conversionID) ? "" : "#"; # We want to put in the template so it is easy to uncomment.
                                    printf("      %sconversion:interpret [          \n",             comment_out);
                                    printf("      %s   conversion:symbol        \"%s\";\n",                 comment_out,interpretAsNull);
                                    printf("      %s   conversion:interpretation conversion:null; \n",comment_out);
                                    printf("      %s];                            \n",               comment_out);
   if(length(dataEnd)) {
                                    printf("      conversion:enhance [        \n");
                                    printf("         ov:csvRow %s;\n",dataEnd);
                                    printf("         a conversion:DataEndRow; \n");
                                    printf("      ];                          \n");
   }
}

{ # length(conversionID) {
   cellValue=$0;

   # If we know there is no header, we can give an example value.
   headerOrExample = (length(header) && header <= 0) ? "conversion:eg " : "ov:csvHeader  ";

   print "      conversion:enhance ["
   printf("         ov:csvCol          %s;\n",NR);
   printf("         %s     \"%s\";\n",headerOrExample,cellValue);
   if(length(conversionID)) {
      # NOTE: This MUST NOT be added to the raw interpretation parameters,
      #       otherwise columns will collapse together prematurely (with human approval).
      printf("         #conversion:label   \"%s\";\n",cellValue);
   }
   printf("         conversion:comment \"\";\n");
   printf("         conversion:range   %s:Literal;\n",RDFS); # Either 'rdfs' or 'todo' (for raw and e*, respectively)
   if(length(conversionID)) {
      if( length(onlyIfCol) && onlyIfCol == i ) {
         print "         a conversion:Only_if_column;"
      }
      if( length(repeatAboveIfEmptyCol) && repeatAboveIfEmptyCol == NR ) {
         print "         a conversion:Repeat_previous_if_empty_column;"
      }
   }
   print "      ];"
}

END {
   print "   ];"
   printf(".");
}

# header2params2.sh
#
# new version of headers2params.sh, processing by line instead of parsing the first line.
#
# Used by $CSV2RDF4LOD_HOME/bin/convert.sh
#
# Parameters:
# -v surrogate
# -v sourceID
# -v datasetID
# -v datasetVersion
# -v subjectDiscriminator
# -v conversionID
#
# -v cellDelimiter
# -v header
# -v dataStart
# -v dataEnd
#
# -v onlyIfCol
# -v repeatAboveIfEmptyCol
# -v interpretAsNull
#
# -v whoami
# -v machine_uri
# -v person_uri

BEGIN {
   ALWAYS_SHOW_CONVERSION_PROCESS = 1; # Added back in to gather empirical results quantifying "effort" to create e1 params.
   showConversionProcess = ALWAYS_SHOW_CONVERSION_PROCESS + length(conversionID) + length(subjectDiscriminator) + length(header) + length(dataStart) + length(interpretAsNull) + length(dataEnd);
   #FS=","
   STEP = length(conversionID) ? sprintf("enhancement/%s",conversionID) : "raw";
   TYPE = length(conversionID) ? "Enhancement" : "Raw";
   # TODO: '|' has no length? --\/
          DELIMTER  = length(cellDelimiter) ? cellDelimiter : "	" # <--- that's a tab character.
   commentDELIMITER = length(cellDelimiter) ? ""            : "#";
   #print "#AWK: cellDelimiter:",cellDelimiter," DELIMITER: ",DELIMITER," comment: ",commentDELIMITER

   if(length(showConversionProcess)) {
      print "@prefix rdf:           <http://www.w3.org/1999/02/22-rdf-syntax-ns#> ."
      print "@prefix rdfs:          <http://www.w3.org/2000/01/rdf-schema#> ."
   }
   RDFS="rdfs"
   if(length(conversionID)) {
      print "@prefix todo:          <http://www.w3.org/2000/01/rdf-schema#> ."
      RDFS="todo"
   }
   print "@prefix xsd:        <http://www.w3.org/2001/XMLSchema#> ."
   if(length(conversionID)) {
      print "@prefix owl:           <http://www.w3.org/2002/07/owl#> ."
      print "@prefix vann:          <http://purl.org/vocab/vann/> ."
      print "@prefix skos:          <http://www.w3.org/2004/02/skos/core#> ."
      print "@prefix time:          <http://www.w3.org/2006/time#> ."
      print "@prefix wgs:           <http://www.w3.org/2003/01/geo/wgs84_pos#> ."
      print "@prefix geonames:      <http://www.geonames.org/ontology#> ."
      print "@prefix geonamesid:    <http://sws.geonames.org/> ."
      print "@prefix govtrackusgov: <http://www.rdfabout.com/rdf/usgov/geo/us/> ."
      print "@prefix dbpedia:       <http://dbpedia.org/resource/> ."
      print "@prefix con:           <http://www.w3.org/2000/10/swap/pim/contact#> ."
      print "@prefix muo:           <http://purl.oclc.org/NET/muo/muo#> ."
   }
   print "@prefix dcterms:       <http://purl.org/dc/terms/> ."
   print "@prefix void:          <http://rdfs.org/ns/void#> ."
   print "@prefix scovo:         <http://purl.org/NET/scovo#> ."
   print "@prefix sioc:          <http://rdfs.org/sioc/ns#> ."
   print "@prefix foaf:          <http://xmlns.com/foaf/0.1/> ."
   print "@prefix ov:            <http://open.vocab.org/terms/> ."
   print "@prefix conversion:    <http://purl.org/twc/vocab/conversion/> ."

   # Converter produces URIs for the LayerDatasets:
   #
   # <http://logd.tw.rpi.edu/source/nitrd-gov/dataset/fedRDnetIT/version/2011-Jan-27/conversion/raw>
   # <http://logd.tw.rpi.edu/source/nitrd-gov/dataset/fedRDnetIT/version/2011-Jan-27/conversion/enhancement/1>
   #
   # To make the params more connected to the datasets, we're replacing this:
   #### NOTE: brought this back for a place for implicit bundles to be named, HOWEVER, the dataset is NOT being named within this:
   printf("@prefix :              <%s/source/%s/dataset/%s/version/%s/params/%s/> .\n",surrogate,sourceID,datasetID,datasetVersion,STEP);
   # with this:
   # Still not right; moved down to subject:
   #printf("@prefix :           <%s/source/%s/dataset/%s/version/%s/conversion/%s> .\n",surrogate,sourceID,datasetID,datasetVersion,STEP);

   #
   # Describe the creator.
   #
   # NOTE: user account and person implemented in bin/util/user-account.sh, too.
                                     print
   if( length(machine_uri) && length(whoami) ) {
      if(length(person_uri)) {
                                    printf("<%s> foaf:holdsAccount <%s%s> .\n",person_uri,   machine_uri,whoami);
      }
                                    printf("<%s%s>\n   a foaf:OnlineAccount;\n   foaf:accountName \"%s\";\n",machine_uri,whoami,   whoami);
                                    printf("   dcterms:isPartOf <%s>;\n",machine_uri);
      if(length(person_uri)) {
                                    printf("   sioc:account_of  <%s>;\n",person_uri);
      }
                                    printf(".\n");
   }else if(length(person_uri)&&length(whoami)) {
                                    printf("<%s> dcterms:identifier \"%s\" .\n",person_uri,whoami);
   }

   #
   # Describe the dataset.
   #
                                     print
                                    printf("<%s/source/%s/dataset/%s/version/%s/conversion/%s>\n",surrogate,sourceID,datasetID,datasetVersion,STEP);
                                     print "   a conversion:LayerDataset, void:Dataset;\n"
                                    printf("   conversion:base_uri           \"%s\"^^xsd:anyURI;\n",surrogate);
                                    printf("   conversion:source_identifier  \"%s\";\n",sourceID);
                                    printf("   conversion:dataset_identifier \"%s\";\n",datasetID);
                                    printf("   conversion:version_identifier \"%s\";\n",datasetVersion);
                                    #printf("   conversion:dataset_version    \"%s\"; # DEPRECATED in favor of version_identifier\n",datasetVersion);
                                     print ""
                                     print "   conversion:conversion_process ["
                                    printf("      a conversion:%sConversionProcess;\n",TYPE);
   if(!length(conversionID))        printf("      conversion:conversion_identifier \"raw\";\n");
   if( length(conversionID))        printf("      conversion:enhancement_identifier \"%s\";\n",conversionID);
   if(length(subjectDiscriminator)) printf("      conversion:subject_discriminator  \"%s\";\n",subjectDiscriminator);

   #
   # Authorship description.
   #
                                     print
   if(length(machine_uri) && length(whoami)) {
                                    printf("      dcterms:creator <%s%s>;\n",machine_uri,whoami); # NOTE: implemented in bin/util/user-account.sh, too.
   }else if(length(person_uri) && length(whoami)) {
                                    printf("      dcterms:creator [ a foaf:OnlineAccount; foaf:accountName \"%s\";\n",whoami);
                                    printf("                        sioc:account_of <%s> ];\n",person_uri);
   }else if(length(whoami)) {
                                    printf("      dcterms:creator [ a foaf:OnlineAccount; foaf:accountName \"%s\" ];\n",whoami);
   }
   if(length(nowXSD)) {
                                    printf("      dcterms:created \"%s\"^^xsd:dateTime;\n\n",nowXSD);
   }

   #
   # Structural enhancement parameters.
   #
                                    printf("      conversion:delimits_cell \"%s\";\n",cellDelimiter);
                                    printf("      #conversion:delimits_cell \"	\"; # tab\n");
                                    printf("      #conversion:delimits_cell \"|\";   # pipe\n");
                                    printf("      #conversion:delimits_cell \",\";   # comma\n");
                                    print
   if(length(header)) {
                                    # Include header info even if just raw.
                                    printf("      conversion:enhance [      \n");
                                    printf("         ov:csvRow %s;\n",header);
                                    printf("         a conversion:HeaderRow;\n");
                                    printf("      ];                        \n");
   }
   if(length(dataStart)) {
                                    printf("      conversion:enhance [          \n");
                                    printf("         ov:csvRow %s;\n",dataStart);
                                    printf("         a conversion:DataStartRow; \n");
                                    printf("      ];                            \n");
   }
   comment_out = length(interpretAsNull) && length(conversionID) ? "" : "#"; # We want to put in the template so it is easy to uncomment.
                                    printf("      %sconversion:interpret [          \n",             comment_out);
                                    printf("      %s   conversion:symbol        \"%s\";\n",                 comment_out,interpretAsNull);
                                    printf("      %s   conversion:interpretation conversion:null; \n",comment_out);
                                    printf("      %s];                            \n",               comment_out);
   if(length(dataEnd)) {
                                    printf("      conversion:enhance [        \n");
                                    printf("         ov:csvRow %s;\n",dataEnd);
                                    printf("         a conversion:DataEndRow; \n");
                                    printf("      ];                          \n");
   }
}

{ # length(conversionID) {
   cellValue=$0;

   # If we know there is no header, we can give an example value.
   headerOrExample = (length(header) && header <= 0) ? "conversion:eg " : "ov:csvHeader  ";

   print "      conversion:enhance ["
   printf("         ov:csvCol          %s;\n",NR);
   printf("         %s     \"%s\";\n",headerOrExample,cellValue);
   if(length(conversionID)) {
      # NOTE: This MUST NOT be added to the raw interpretation parameters,
      #       otherwise columns will collapse together prematurely (with human approval).
      printf("         #conversion:label   \"%s\";\n",cellValue);
   }
   printf("         conversion:comment \"\";\n");
   printf("         conversion:range   %s:Literal;\n",RDFS); # Either 'rdfs' or 'todo' (for raw and e*, respectively)
   if(length(conversionID)) {
      if( length(onlyIfCol) && onlyIfCol == i ) {
         print "         a conversion:Only_if_column;"
      }
      if( length(repeatAboveIfEmptyCol) && repeatAboveIfEmptyCol == NR ) {
         print "         a conversion:Repeat_previous_if_empty_column;"
      }
   }
   print "      ];"
}

END {
   print "   ];"
   printf(".");
}


moved to Transdipporator for now

moved to Transdipporator for now

#! /usr/bin/awk -f
# turtle_merge.awk  t_1.ttl t_2.ttl > t_3.ttl
#
# Notes:
# You could merge more than two files
#
# Written to merge some small turtle formatted _METADATA_ files
# that is "small", as in maybe a page long files (i.e. a few kb)

# This script does not know anything about IRI or curies
# just plain ol' string pattern matching.

# If multiple prefixes have different base-uri then the last one wins
#
# Order is neither preserved nor reliably repeated.
#
# There may be room to reduce redundancy in object lists in some cases

BEGIN{RS= " \\.\n*"}

# rdf prefix declarations
/^@prefix /{prefix[$2]=$3}

# rdf record
/^<[^>].*> / {
    # isolate subject
    s = $1; $1 = "";
    # strip newlines
    gsub("\n", "")
    # collapse space
    gsub("  ", " ")
    # partition predicates list
    split(substr($0,2), plist, " ; ")
    for(pos in plist){
        prdobjs = plist[pos]
        p = substr(prdobjs, 1, index(prdobjs, " "))
        prdobjs = substr(prdobjs, length(p)+1)
        # what remains are objects
        record[s,p] = prdobjs
    }
}

END {
    for(x in prefix){print "@prefix " x " " prefix[x] " ."}
    print ""
    # regroup by subjects
    for(r in record){
        split(r, sp, SUBSEP)
        s = sp[1]; p = sp[2]
        subject[s] = subject[s] "\t" p " " record[r] " ;\n"
    }

    # resorting could happen here

    for(s in subject){
        print s
        print substr(subject[s],1, length(subject[s])-3) " .\n"
    }
}


Finish out tmp bed for paired end

Finish out tmp bed for paired end

This is based on the mpavis.sh form hichip method of making the
temporary bed file using the tlen for the end

BEGIN{
  FS="\t";
  OFS="\t";
  alignments=0;
  if ("" == base) {
    print "Missing output base via -v base=";
    exit 1;
  }
  if ("" == endness) {
    print "Missing endness style (se|pe) via -v endness=";
    exit 1;
  } else if ( ("se" == endness) && (""==size) ) {
    print "Missing fragment size since single end via -v size=";
    exit 1;
  }
}

function pe_bedder(path) {
  start=($4-1)
  if ( (($2==83) || ($2==147)) && ($9>0) ) {
    print $3,start,(start+$9),".","1","-" > path;
  } else if ( ((2==83) || ($2==147)) && ($9<0) ) {
    print $3,start,(start-$9),".","1","-" > path;
  } else if ( (($2==99) || ($2==163)) && ($9>0) ) {
    print $3,start,(start+$9),".","1","+" > path;
  } else if ( (($2==99) || ($2==163)) && ($9<0) ) {
    print $3,start,(start-$9),".","1","+" > path;
  }
}

function se_bedder(path,size) {
}

{
  alignments++;
  if ("pe" == endness) {
    sub(/-/,"",$9);
    tlens[$9]++;
    pe_bedder(base"_tmp.bed");
  } else if ("se" == endness) {
  }
}

END {
  print alignments > base"_num_alignments.txt";
  if ("pe" == endness) {
    output = " sort -k 2 -n -r|head -n 1|cut -f 1 >" base"_estimated_size.txt";
    for(tlen in tlens) {
      print tlen,tlens[tlen] | output;
    }
  }
}

BEGIN{
  FS="\t";
  OFS="\t";
  alignments=0;
  if ("" == base) {
    print "Missing output base via -v base=";
    exit 1;
  }
  if ("" == endness) {
    print "Missing endness style (se|pe) via -v endness="
    exit 1;
  }
}

function pe_bedder(path) {

}

function se_bedder(path,size) {
}

{
  alignments++;
  if ("pe" == endness) {
    sub(/-/,"",$9);
    tlens[$9]++;
  } else if ("se" == endness) {
  }
}

END {
  print alignments > base"_num_alignments.txt";
  if ("pe" == endness) {
    output = " sort -k 2 -n -r|head -n 1|cut -f 1 >" base"_estimated_size.txt";
    for(tlen in tlens) {
      print tlen,tlens[tlen] | output;
    }
  }
}


Define a specific map for the Apple portuguese USB keyboards.

Based on input from Manuel Pata and Rodolfo Gouveia on tech@.

#! /usr/bin/awk -f
#	$OpenBSD: makemap.awk,v 1.2 2005/05/12 09:28:21 miod Exp $
#
# Copyright (c) 2005, Miodrag Vallat
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
#
# This script attempts to convert, with minimal hacks and losses, the
# regular PS/2 keyboard (pckbd) layout tables into USB keyboard (ukbd)
# layout tables.
#

BEGIN {
	rcsid = "$OpenBSD: makemap.awk,v 1.2 2005/05/12 09:28:21 miod Exp $"
	ifdepth = 0
	ignore = 0
	declk = 0
	haskeys = 0

	# PS/2 id -> UKBD conversion table, or "sanity lossage 102"
	# (101 is for GSC keyboards!)
	for (i = 0; i < 256; i++)
		conv[i] = -1

	conv[1] = 41
	conv[2] = 30
	conv[3] = 31
	conv[4] = 32
	conv[5] = 33
	conv[6] = 34
	conv[7] = 35
	conv[8] = 36
	conv[9] = 37
	conv[10] = 38
	conv[11] = 39
	conv[12] = 45
	conv[13] = 46
	conv[14] = 42
	conv[15] = 43
	conv[16] = 20
	conv[17] = 26
	conv[18] = 8
	conv[19] = 21
	conv[20] = 23
	conv[21] = 28
	conv[22] = 24
	conv[23] = 12
	conv[24] = 18
	conv[25] = 19
	conv[26] = 47
	conv[27] = 48
	conv[28] = 40
	conv[29] = 224
	conv[30] = 4
	conv[31] = 22
	conv[32] = 7
	conv[33] = 9
	conv[34] = 10
	conv[35] = 11
	conv[36] = 13
	conv[37] = 14
	conv[38] = 15
	conv[39] = 51
	conv[40] = 52
	conv[41] = 53
	conv[42] = 225
	conv[43] = 50
	conv[44] = 29
	conv[45] = 27
	conv[46] = 6
	conv[47] = 25
	conv[48] = 5
	conv[49] = 17
	conv[50] = 16
	conv[51] = 54
	conv[52] = 55
	conv[53] = 56
	conv[54] = 229
	conv[55] = 85
	conv[56] = 226
	conv[57] = 44
	conv[58] = 57
	conv[59] = 58
	conv[60] = 59
	conv[61] = 60
	conv[62] = 61
	conv[63] = 62
	conv[64] = 63
	conv[65] = 64
	conv[66] = 65
	conv[67] = 66
	conv[68] = 67
	conv[69] = 83
	conv[70] = 71
	conv[71] = 95
	conv[72] = 96
	conv[73] = 97
	conv[74] = 86
	conv[75] = 92
	conv[76] = 93
	conv[77] = 94
	conv[78] = 87
	conv[79] = 89
	conv[80] = 90M
	conv[81] = 91
	conv[82] = 98
	conv[83] = 99
	conv[86] = 100
	conv[87] = 68
	conv[88] = 69
	conv[112] = 135
	conv[115] = 136
	conv[121] = 137
	conv[123] = 138
	conv[125] = 139
	conv[127] = 72
	conv[156] = 88
	conv[157] = 228
	conv[170] = 70
	conv[181] = 84
	conv[184] = 230
	# 198 is #if 0 in the PS/2 map...
	conv[199] = 74
	conv[200] = 82
	conv[201] = 75
	conv[203] = 80
	conv[205] = 79
	conv[207] = 77
	conv[208] = 81
	conv[209] = 78
	conv[210] = 73
	conv[211] = 99
	conv[219] = 227
	conv[220] = 231
	conv[221] = 101
}
NR == 1 {
	VERSION = $0
	gsub("\\$", "", VERSION)
	gsub("\\$", "", rcsid)

	printf("/*\t\$OpenBSD\$\t*/\n\n")
	printf("/*\n")
	printf(" * THIS FILE IS AUTOMAGICALLY GENERATED.  DO NOT EDIT.\n")
	printf(" *\n")
	printf(" * generated by:\n")
	printf(" *\t%s\n", rcsid)
	printf(" * generated from:\n")
	printf(" */\n")
	print VERSION

	next
}

#
# A very limited #if ... #endif parser. We only want to correctly detect
# ``#if 0'' constructs, so as not to process their contents. This is necessary
# since our output is out-of-order from our input.
#
# Note that this does NOT handle ``#ifdef notyet'' correctly - please only use
# ``#if 0'' constructs in the input.
#

/^#if/ {
	ignores[ifdepth] = ignore
	if ($2 == "0")
		ignore = 1
	else
		ignore = 0
	ifdepth++
	if (ignore)
		next
}
/^#endif/ {
	oldignore = ignore
	ifdepth--
	ignore = ignores[ifdepth]
	ignores[ifdepth] = 0
	if (oldignore)
		next
}

$1 == "#include" {
	if (ignore)
		next
	if ($2 == "<dev/pckbc/wskbdmap_mfii.h>")
		print "#include <dev/usb/usb_port.h>"
	else
		printf("#include %s\n", $2)

	next
}
$1 == "#define" || $1 == "#undef" {
	if (ignore)
		next
	print $0
	next
}

# Don't bother converting the DEC LK layout.
/declk\[/ {
	declk = 1
	next
}
/declk/ {
	next
}

/pckbd/ {
	gsub("pckbd", "ukbd", $0)
	mapname = $4
}

/KC/ {
	if (ignore)
		next

	if (declk)
		next

	haskeys = 1

	sidx = substr($1, 4, length($1) - 5)
	orig = int(sidx)
	id = conv[orig]

	# 183 is another Print Screen...
	if (orig == 183)
		next

	if (id == -1) {
		printf("/* initially KC(%d),", orig)
		for (f = 2; f <= NF; f++) {
			if ($f != "/*" && $f != "*/")
				printf("\t%s", $f)
		}
		printf("\t*/\n")
	} else {
		lines[id] = sprintf("    KC(%d),", id)
		#
		# This makes sure that the non-comment part of the output
		# ends up with a trailing comma. This is necessary since
		# the last line of an input block might not have a trailing
		# comma, but might not be the last line of an output block
		# due to sorting.
		#
		comma = 0
		for (f = 2; f <= NF; f++) {
			if ($f == "/*")
				comma++
			if (comma == 0 &&
			    substr($f, length($f)) != ",") {
				lines[id] = sprintf("%s\t%s,", lines[id], $f)
			} else {
				lines[id] = sprintf("%s\t%s", lines[id], $f)
			}
			if ($f == "*/")
				comma--
		}
	}

	next
}
/};/ {
	if (ignore)
		next

	if (declk) {
		declk = 0
		next
	}

	if (haskeys) {
		# Duplicate 42 (backspace) as 76
		# XXX maybe not correct anymore?
		lines[76] = lines[42]
		sub("42", "76", lines[76])

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

		haskeys = 0

		#
		# Apple portuguese USB keyboards use a slightly different
		# layout. We define it here.
		#
		if (mapname == "ukbd_keydesc_pt[]") {
			print $0
			print "\nstatic const keysym_t ukbd_keydesc_pt_apple[] = {"
			print "/*  pos\t\tnormal\t\tshifted */"
			print "    KC(46),\tKS_plus,\tKS_asterisk,"
			print "    KC(47),\tKS_masculine,\tKS_ordfeminine,"
			print "    KC(50),\tKS_backslash,\tKS_bar,"
			print "    KC(52),\tKS_dead_tilde,\tKS_dead_circumflex"
		}

	}
}
/KB_PT/ {
	print $0
	print "\tKBD_MAP(KB_PT | KB_APPLE,\tKB_PT,\tukbd_keydesc_pt_apple),"
	next
}
{
	if (ignore)
		next
	if (declk)
		next
	print $0
}

#! /usr/bin/awk -f
#	$OpenBSD: makemap.awk,v 1.1 2005/05/09 05:08:32 miod Exp $
#
# Copyright (c) 2005, Miodrag Vallat
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
#
# This script attempts to convert, with minimal hacks and losses, the
# regular PS/2 keyboard (pckbd) layout tables into USB keyboard (ukbd)
# layout tables.
#

BEGIN {
	rcsid = "$OpenBSD: makemap.awk,v 1.1 2005/05/09 05:08:32 miod Exp $"
	ifdepth = 0
	ignore = 0
	declk = 0

	# PS/2 id -> UKBD conversion table, or "sanity lossage 102"
	# (101 is for GSC keyboards!)
	for (i = 0; i < 256; i++)
		conv[i] = -1

	conv[1] = 41
	conv[2] = 30
	conv[3] = 31
	conv[4] = 32
	conv[5] = 33
	conv[6] = 34
	conv[7] = 35
	conv[8] = 36
	conv[9] = 37
	conv[10] = 38
	conv[11] = 39
	conv[12] = 45
	conv[13] = 46
	conv[14] = 42
	conv[15] = 43
	conv[16] = 20
	conv[17] = 26
	conv[18] = 8
	conv[19] = 21
	conv[20] = 23
	conv[21] = 28
	conv[22] = 24
	conv[23] = 12
	conv[24] = 18
	conv[25] = 19
	conv[26] = 47
	conv[27] = 48
	conv[28] = 40
	conv[29] = 224
	conv[30] = 4
	conv[31] = 22
	conv[32] = 7
	conv[33] = 9
	conv[34] = 10
	conv[35] = 11
	conv[36] = 13
	conv[37] = 14
	conv[38] = 15
	conv[39] = 51
	conv[40] = 52
	conv[41] = 53
	conv[42] = 225
	conv[43] = 50
	conv[44] = 29
	conv[45] = 27
	conv[46] = 6
	conv[47] = 25
	conv[48] = 5
	conv[49] = 17
	conv[50] = 16
	conv[51] = 54
	conv[52] = 55
	conv[53] = 56
	conv[54] = 229
	conv[55] = 85
	conv[56] = 226
	conv[57] = 44
	conv[58] = 57
	conv[59] = 58
	conv[60] = 59
	conv[61] = 60
	conv[62] = 61
	conv[63] = 62
	conv[64] = 63
	conv[65] = 64
	conv[66] = 65
	conv[67] = 66
	conv[68] = 67
	conv[69] = 83
	conv[70] = 71
	conv[71] = 95
	conv[72] = 96
	conv[73] = 97
	conv[74] = 86
	conv[75] = 92
	conv[76] = 93
	conv[77] = 94
	conv[78] = 87
	conv[79] = 89
	conv[80] = 90M
	conv[81] = 91
	conv[82] = 98
	conv[83] = 99
	conv[86] = 100
	conv[87] = 68
	conv[88] = 69
	conv[112] = 135
	conv[115] = 136
	conv[121] = 137
	conv[123] = 138
	conv[125] = 139
	conv[127] = 72
	conv[156] = 88
	conv[157] = 228
	conv[170] = 70
	conv[181] = 84
	conv[184] = 230
	# 198 is #if 0 in the PS/2 map...
	conv[199] = 74
	conv[200] = 82
	conv[201] = 75
	conv[203] = 80
	conv[205] = 79
	conv[207] = 77
	conv[208] = 81
	conv[209] = 78
	conv[210] = 73
	conv[211] = 99
	conv[219] = 227
	conv[220] = 231
	conv[221] = 101
}
NR == 1 {
	VERSION = $0
	gsub("\\$", "", VERSION)
	gsub("\\$", "", rcsid)

	printf("/*\t\$OpenBSD\$\t*/\n\n")
	printf("/*\n")
	printf(" * THIS FILE IS AUTOMAGICALLY GENERATED.  DO NOT EDIT.\n")
	printf(" *\n")
	printf(" * generated by:\n")
	printf(" *\t%s\n", rcsid)
	printf(" * generated from:\n")
	printf(" */\n")
	print VERSION

	next
}

#
# A very limited #if ... #endif parser. We only want to correctly detect
# ``#if 0'' constructs, so as not to process their contents. This is necessary
# since our output is out-of-order from our input.
#
# Note that this does NOT handle ``#ifdef notyet'' correctly - please only use
# ``#if 0'' constructs in the input.
#

/^#if/ {
	ignores[ifdepth] = ignore
	if ($2 == "0")
		ignore = 1
	else
		ignore = 0
	ifdepth++
	if (ignore)
		next
}
/^#endif/ {
	oldignore = ignore
	ifdepth--
	ignore = ignores[ifdepth]
	ignores[ifdepth] = 0
	if (oldignore)
		next
}

$1 == "#include" {
	if (ignore)
		next
	if ($2 == "<dev/pckbc/wskbdmap_mfii.h>")
		print "#include <dev/usb/usb_port.h>"
	else
		printf("#include %s\n", $2)

	next
}
$1 == "#define" || $1 == "#undef" {
	if (ignore)
		next
	print $0
	next
}

# Don't bother converting the DEC LK layout.
/declk\[/ {
	declk = 1
	next
}
/declk/ {
	next
}

/pckbd/ {
	gsub("pckbd", "ukbd", $0)
	print $0
	next
}

/KC/ {
	if (ignore)
		next

	if (declk)
		next

	sidx = substr($1, 4, length($1) - 5)
	orig = int(sidx)
	id = conv[orig]

	# 183 is another Print Screen...
	if (orig == 183)
		next

	if (id == -1) {
		printf("/* initially KC(%d),", orig)
		for (f = 2; f <= NF; f++) {
			if ($f != "/*" && $f != "*/")
				printf("\t%s", $f)
		}
		printf("\t*/\n")
	} else {
		lines[id] = sprintf("    KC(%d),", id)
		#
		# This makes sure that the non-comment part of the output
		# ends up with a trailing comma. This is necessary since
		# the last line of an input block might not have a trailing
		# comma, but might not be the last line of an output block
		# due to sorting.
		#
		comma = 0
		for (f = 2; f <= NF; f++) {
			if ($f == "/*")
				comma++
			if (comma == 0 &&
			    substr($f, length($f)) != ",") {
				lines[id] = sprintf("%s\t%s,", lines[id], $f)
			} else {
				lines[id] = sprintf("%s\t%s", lines[id], $f)
			}
			if ($f == "*/")
				comma--
		}
	}

	next
}
/};/ {
	if (ignore)
		next

	if (declk) {
		declk = 0
		next
	}

	# Duplicate 42 (backspace) as 76
	# XXX maybe not correct anymore?
	lines[76] = lines[42]
	sub("42", "76", lines[76])

	for (i = 0; i < 256; i++)
		if (lines[i]) {
			print lines[i]
			lines[i] = ""
		}
}
{
	if (ignore)
		next
	if (declk)
		next
	print $0
}


cut deadwood, add exceptions, split bnodes into their own pattern rules

#! /usr/bin/awk -f

#  Reduce the subject and object of RDF triples (ntriples format)
# down to their @prefix (or literal object class)
#  Reduce predicates to the specific identifier and
# the ontology they are from.(curi form)
#  Express the subject and object as nodes with a directed edge
# labeled with the predicate in the graphviz dot format
#  Include a tally of each combination of nodes and edge

#  This may over generalize in some cases because I do not have
# a handy way to differentiate uri for subjects and objects
# which may belong to a "structural" ontology as opposed to
# a data uri.

#  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 string <>
function trim(str){
	return substr(str,2,length(str)-2)
}

########################################################
# 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 other uri use differently
function stripid(uri){
	# <_:blanknode> are not allowed in ntriples (but may happen anyway)
	if(0 < 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 || char=="")
		# we don't know what it is, a literal perhaps or uri fragment
		return uri
	else
		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)
	gsub(/__*/,"_",str)
	return str
}

# if possible, find a shorter form for the input
function contract(uri){
	u = uri
	# shorten till longest uri in curi map is found (or not)
	while(!(u in prefix) &&  length(u))
		u = stripid(substr(u,1,length(u)-1))
	if(u in prefix)
		return prefix[u]
	else{
		# printf("WARN  %s\n", uri) > "/dev/stderr"
		return simplify(uri)
	}
}

# get the final (incl fragment identifier) portion of a slashed path
function final(uri){
	split(uri, b, "/")
	p = b[length(b)]
	anchor = match(p, "#")
	if(anchor > 0)
		p = substr(p, anchor+1)
	return p
}

BEGIN{
	# exceptions
	prefix["BNODE"]="BNODE"  # is a fixed point
	prefix["https://monarchinitiative.org/_"]="BNODE"
	# just until skolemized bnodes get in the curie map?
	prefix["https://monarchinitiative.org/.well-known/genid"]="BNODE"
	############################################################
	# revisit whether these exceptions are still necessary often
	# they may have been moved into the  prefix mapping file
	prefix["http://www.w3.org/1999/02/22-rdf-syntax-ns#"]="rdf"
	prefix["http://www.w3.org/2000/01/rdf-schema#"]="rdfs"
	prefix["http://www.w3.org/2002/07/owl#"]="owl"
	# in mgi
	prefix["https://www.mousephenotype.org"]="IMPC"
	# in panther
	prefix["http://identifiers.org/wormbase"]="WormBase"
	# in IMPC
	prefix["http://www.mousephenotype.org"]="IMPC"
	# in GWAScatalog
	prefix["http://www.ncbi.nlm.nih.gov/SNP/"]="dbSNP"
	# till all non httpS: are purged
	prefix["http://monarchinitiative.org/"]="BASE"
	prefix["http://www.monarchinitiative.org/"]="BASE"
	prefix["http://monarchinitiative.org/MONARCH_"]="MONARCH"
	prefix["http://www.monarchinitiative.org/MONARCH"]=""
	prefix["http://www.monarchinitiative.org/MONARCH_"]="MONARCH"
	prefix["http://data.monarchinitiative.org/ttl"]="MonarchData"
	prefix["http://archive.monarchinitiative.org/ttl"]="MonarchArchive"
}

# main loop
# parse and stash the curie yaml file (first file)
# YAML format is tic delimited word (the curi prefix)
# optional whitespace, a colon, optional whitespace
# then a tic delimited url
# (FNR == NR) && /^'[^']*' *: 'http[^']*'.*/ { # loosing some?
(FNR == NR) && /^'.*/ {
	split($0, arr, "'")
	if(arr[2]=="")
		arr[2]="BASE"
	prefix[arr[4]]=arr[2]
}

# process the ntriple file(s)  which are not the first file

### subject predicate and object are all uri
(FNR != NR) && /^<[^>]*> <[^>]*> <[^>]*> \.$/ {
	s = contract(stripid(trim($1)))
	p =  final(trim($2))
	ns = contract(stripid(trim($2)))
	o = contract(stripid(trim($3)))
	edgelist[s,ns ":" p,o]++
	done[NR]=1
}
### subject & predicate are uri but the object is a literal
(FNR != NR) && /^<[^>]*> <[^>]*> "[^"]*".*\.$/ {
	s = contract(stripid(trim($1)))
	p = final(trim($2))
	ns = contract(stripid(trim($2)))
	edgelist[s, ns ":" p, "LITERAL"]++
	done[NR]=1
}
### subject is a bare blank node, predicate and object are uri
(FNR != NR) && /^_:[^ ]* <[^>]*> <[^>]*> \.$/ {
	# once our bnode syntax is uniform we may want more info out of it
	# s = contract(stripid($1))
	p =  final(trim($2))
	ns = contract(stripid(trim($2)))
	### Object (like subject)
	o = contract(stripid(trim($3)))
	edgelist["BNODE",ns ":" p,o]++
	done[NR]=1
}
### subject & predicate are uri & object is a bare blank node
(FNR != NR) && /^<[^>]*> <[^>]*> _:[^ ]* \.$/ {
	s = contract(stripid(trim($1)))
	p =  final(trim($2))
	ns = contract(stripid(trim($2)))
	#o = contract(stripid($3))
	edgelist[s,ns ":" p,"BNODE"]++
	done[NR]=1
}
### subject and object are a bare blank nodes, predicate is a uri
(FNR != NR) && /^_:[^ ]* <[^>]*> _:[^ ]* \.$/ {
	# s = contract(stripid($1))
	p =  final(trim($2))
	ns = contract(stripid(trim($2)))
	# o = contract(stripid($3))
	edgelist["BNODE",ns ":" p,"BNODE"]++
	done[NR]=1
}
### subject is a bare blank node, predicate is a uri & the object is a literal
(FNR != NR) && /^_:[^ ]* <[^>]*> "[^"]*".*\.$/ {
	# s = contract(stripid($1))
	p = final(trim($2))
	ns = contract(stripid(trim($2)))
	edgelist["BNODE", ns ":" p, "LITERAL"]++
	done[NR]=1
}

# print anything else so it makes itself known
(FNR != NR) && (done[NR]<1) && (NF>1){
	printf("ERROR? line %i  %s", FNR, $0) > "/dev/stderr"
}

# output dot file, include edge counts
END{
	print "digraph {"
	print "rankdir=LR;"
	print "charset=\"utf-8\";"
	for(edge in edgelist){
		split(edge ,spo, SUBSEP);
		print simplify(spo[1]) " -> " simplify(spo[3]) \
		" [label=\"" spo[2] " (" edgelist[edge] ")\"];"
	}
	print "LITERAL [shape=record];"
	print "labelloc=\"t\";"
	title = final(FILENAME)
	datestamp = strftime("%Y%m%d", systime())
	print "label=\"" substr(title,1,length(title)-3) " (" datestamp ")\";"
	print "}"
}

#! /usr/bin/awk -f

#  Reduce the subject and object of RDF triples (ntriples format)
# down to their @prefix (or literal object class)
#  Reduce predicates to the specific identifier and
# the ontology they are from.(curi form)
#  Express the subject and object as nodes with a directed edge
# labeled with the predicate in the graphviz dot format
#  Include a tally of each combination of nodes and edge

#  This may over generalize in some cases because I do not have
# a handy way to differentiate uri for subjects and objects
# which may belong to a "structural" ontology as opposed to
# a data uri.

#  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 string <>
function trim(str){
	return substr(str,2,length(str)-2)
}

########################################################
# 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){
	# <_: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 || char=="")
		# we don't know what it is, a literal perhaps or uri fragment
		return uri
	else
		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)
	gsub(/__*/,"_",str)
	return str
}

# if possible, find a shorter form for the input
function contract(uri){
	u = uri
	# shorten till longest uri in curi map is found (or not)
	while(!(u in prefix))
		u = stripid(substr(u,1,length(u)-1))
	if(u in prefix)
		return prefix[u]
	else
		return simplify(uri)
}

# get the final (incl fragment identifier) portion of a slashed path
function final(uri){
	split(uri, b, "/")
	p = b[length(b)]
	anchor = match(p, "#")
	if(anchor > 0)
		p = substr(p, anchor+1)
	return p
}

BEGIN{
	# exceptions
	prefix["BNODE"]="BNODE"  # is a fixed point
	prefix["https://monarchinitiative.org/_"]="BNODE"
	# just until skolemized bnodes get in the curie map?
	prefix["https://monarchinitiative.org/.well-known/genid"]="BNODE"
	# revisit if exceptions are still necessary
	prefix["http://www.w3.org/1999/02/22-rdf-syntax-ns#"]="rdf"
	prefix["http://www.w3.org/2000/01/rdf-schema#"]="rdfs"
	prefix["http://www.w3.org/2002/07/owl#"]="owl"
	# in mgi
	prefix["https://www.mousephenotype.org"]="IMPC"
	# in panther
	prefix["http://identifiers.org/wormbase"]="WormBase"
	# till all non httpS: are purged
	prefix["http://monarchinitiative.org/"]="BASE"
	prefix["http://www.monarchinitiative.org/"]="BASE"
	prefix["http://monarchinitiative.org/MONARCH_"]="MONARCH"
	prefix["http://www.monarchinitiative.org/MONARCH_"]="MONARCH"
}

# main loop
# 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, "'")
	if(arr[2]=="")
		arr[2]="BASE"
	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
(FNR != NR) && /^<[^>]*> <[^>]*> <[^>]*> \.$/ {
	### Subject (uri)
	s = contract(stripid(trim($1)))
	### Predicate (uri)
	p =  final(trim($2))
	ns = contract(stripid(trim($2)))
	### Object (like subject)
	o = contract(stripid(trim($3)))
	edgelist[s,ns ":" p,o]++
}
### case when the object is a literal
(FNR != NR) && /^<[^>]*> <[^>]*> "[^"]*" \.$/ {
	### Subject (uri)
	s = contract(stripid(trim($1)))
	### Predicate (uri)
	p = final(trim($2))
	ns = contract(stripid(trim($2)))
	### not a uri
	o = "LITERAL"
	edgelist[s, ns ":" p, o]++
	nodelist[o " [shape=record];"]++
}

# output dot file, include edge counts
END{
	print "digraph {"
	print "rankdir=LR;"
	print "charset=\"utf-8\";"
	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)
	datestamp = strftime("%Y%m%d", systime())
	print "label=\"" substr(title,1,length(title)-3) " (" datestamp ")\";"
	print "}"
}


Removes the first space after the leading `*` in a comment, because some parsers *cough*markdeep*cough* don't like it if there is a space before the `[link]: www.example.com`

#! /usr/bin/awk -f
#
# Extracts the /**-denoted comments from a source file.
# https://github.com/wernsey/d.awk
#
# (c) 2016 Werner Stoop
# Copying and distribution of this file, with or without modification,
# are permitted in any medium without royalty provided the copyright
# notice and this notice are preserved. This file is offered as-is,
# without any warranty.

!Multi && /\/\*\*/ {
    sub(/^.*\/\*\*/,"");
    if(match($0,/\*\//)) {
        sub(/\*\/.*/,"");
        print "\n" $0 "\n";
    } else {
        Multi = 1;
        print;
    }
}
Multi && /\*\// {
    sub(/[[:space:]]*\*[[:space:]]?\/.*/,"");
    if($0) {
        sub(/^[[:space:]]*\*[[:space:]]?/,"");
        print $0 "\n";
    } else print "";
    Multi = 0;
}
Multi && /^[[:space:]]*\*/ {
    sub(/^[[:space:]]*\*[[:space:]]?/,"");
    print;
}
#Multi { print; }

# For `///` single-line comments:
Single && $0 !~ /\/\/\// {
    Single=0;
    print "\n";
}
Single && /\/\/\// {
    sub(/^.*\/\/\//,"");
    print $0;
}
!Single && /\/\/\// {
    sub(/^.*\/\/\//,"");
    print $0;
    Single=1;
}

#! /usr/bin/awk -f
#
# Extracts the /**-denoted comments from a source file.
# https://github.com/wernsey/d.awk
#
# (c) 2016 Werner Stoop
# Copying and distribution of this file, with or without modification,
# are permitted in any medium without royalty provided the copyright
# notice and this notice are preserved. This file is offered as-is,
# without any warranty.

!Multi && /\/\*\*/ {
    sub(/^.*\/\*\*/,"");
    if(match($0,/\*\//)) {
        sub(/\*\/.*/,"");
        print "\n" $0 "\n";
    } else {
        Multi = 1;
        print;
    }
}
Multi && /\*\// {
    sub(/[[:space:]]*\*\/.*/,"");
    if($0) {
        sub(/^[[:space:]]*\*/,"");
        print $0 "\n";
    } else print "";
    Multi = 0;
}
Multi && /^[[:space:]]*\*/ {
    sub(/^[[:space:]]*\*/,"");
    print;
}
#Multi { print; }

# For `///` single-line comments:
Single && $0 !~ /\/\/\// {
    Single=0;
    print "\n";
}
Single && /\/\/\// {
    sub(/^.*\/\/\//,"");
    print $0;
}
!Single && /\/\/\// {
    sub(/^.*\/\/\//,"");
    print $0;
    Single=1;
}


c++: Fix for symbol table demangled names with spaces

#
# Converts the output of 'nm' into a C source containing an array of symbols
# that correspond to functions (t and T in terms of 'nm').
#
# Usage:
#   nm -n image | awk -f nm2c.awk
#
#   Date: Aug 28, 2012
# Author: Eldar Abusalimov
#

BEGIN {
	print "/* Auto-generated file. Do not edit. */";
	print "";
	print "#include <debug/symbol.h>";
	print "#include <stddef.h>";
	print "";
	print "const struct symbol __symbol_table[] = {";
}

/^[0-9a-fA-F]* [tT]/ {
	split($0,a," [tT] ");
	printf "\t{ (void *) 0x%s, \"%s\" },\n", $1, a[2];
}

END {
	print "};";
	print "const size_t __symbol_table_size =";
	print "\tsizeof(__symbol_table) / sizeof(__symbol_table[0]);";
	print "";
}

#
# Converts the output of 'nm' into a C source containing an array of symbols
# that correspond to functions (t and T in terms of 'nm').
#
# Usage:
#   nm -n image | awk -f nm2c.awk
#
#   Date: Aug 28, 2012
# Author: Eldar Abusalimov
#

BEGIN {
	print "/* Auto-generated file. Do not edit. */";
	print "";
	print "#include <debug/symbol.h>";
	print "#include <stddef.h>";
	print "";
	print "const struct symbol __symbol_table[] = {";
}

/^[0-9a-fA-F]* [tT]/ {
	printf "\t{ (void *) 0x%s, \"%s\" },\n", $1, $3;
}

END {
	print "};";
	print "const size_t __symbol_table_size =";
	print "\tsizeof(__symbol_table) / sizeof(__symbol_table[0]);";
	print "";
}


Filter out --with-* in tool/.configure.awk

#!/command/mawk

BEGIN {
    print "#!/command/mawk" "\n\n" "BEGIN { OFS = \"=\" }"
}

$1 ~ /^--with-/ { next }
$1 !~ /dir$/ { next }
{ OPTION = $0 }
{ gsub("-","",OPTION) }
{ print "$1 == \"" $0 "\" { print $0," toupper(OPTION) " }" }

#!/command/mawk

BEGIN {
    print "#!/command/mawk" "\n\n" "BEGIN { OFS = \"=\" }"
}

$1 !~ /dir$/ { next }
{ OPTION = $0 }
{ gsub("-","",OPTION) }
{ print "$1 == \"" $0 "\" { print $0," toupper(OPTION) " }" }


#105425# filter comments

#105425# filter comments

#*************************************************************************
#
#   $RCSfile: getcsym.awk,v $
#
#   $Revision: 1.2 $
#
#   last change: $Author: hjs $ $Date: 2002-11-21 16:50:30 $
#
#   The Contents of this file are made available subject to the terms of
#   either of the following licenses
#
#          - GNU Lesser General Public License Version 2.1
#          - Sun Industry Standards Source License Version 1.1
#
#   Sun Microsystems Inc., October, 2000
#
#   GNU Lesser General Public License Version 2.1
#   =============================================
#   Copyright 2000 by Sun Microsystems, Inc.
#   901 San Antonio Road, Palo Alto, CA 94303, USA
#
#   This library is free software; you can redistribute it and/or
#   modify it under the terms of the GNU Lesser General Public
#   License version 2.1, as published by the Free Software Foundation.
#
#   This library is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#   Lesser General Public License for more details.
#
#   You should have received a copy of the GNU Lesser General Public
#   License along with this library; if not, write to the Free Software
#   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
#   MA  02111-1307  USA
#
#
#   Sun Industry Standards Source License Version 1.1
#   =================================================
#   The contents of this file are subject to the Sun Industry Standards
#   Source License Version 1.1 (the "License"); You may not use this file
#   except in compliance with the License. You may obtain a copy of the
#   License at http://www.openoffice.org/license.html.
#
#   Software provided under this License is provided on an "AS IS" basis,
#   WITHOUT WARRUNTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
#   WITHOUT LIMITATION, WARRUNTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
#   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
#   See the License for the specific provisions governing your rights and
#   obligations concerning the Software.
#
#   The Initial Developer of the Original Code is: Sun Microsystems, Inc..
#
#   Copyright: 2000 by Sun Microsystems, Inc.
#
#   All Rights Reserved.
#
#   Contributor(s): _______________________________________
#
#
#
#*************************************************************************
BEGIN { global_found = "false" }
/[ \t]*#/ { sub( substr( $0, index($0, "#")),"" ) }
/[ \t]*local:/ { global_found = "false" }
/^[ \t]*$/ { next }
global_found == "true"  { print $0 }
/[ \t]*global:/ { global_found = "true" }

#*************************************************************************
#
#   $RCSfile: getcsym.awk,v $
#
#   $Revision: 1.1 $
#
#   last change: $Author: hjs $ $Date: 2001-04-27 12:46:32 $
#
#   The Contents of this file are made available subject to the terms of
#   either of the following licenses
#
#          - GNU Lesser General Public License Version 2.1
#          - Sun Industry Standards Source License Version 1.1
#
#   Sun Microsystems Inc., October, 2000
#
#   GNU Lesser General Public License Version 2.1
#   =============================================
#   Copyright 2000 by Sun Microsystems, Inc.
#   901 San Antonio Road, Palo Alto, CA 94303, USA
#
#   This library is free software; you can redistribute it and/or
#   modify it under the terms of the GNU Lesser General Public
#   License version 2.1, as published by the Free Software Foundation.
#
#   This library is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#   Lesser General Public License for more details.
#
#   You should have received a copy of the GNU Lesser General Public
#   License along with this library; if not, write to the Free Software
#   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
#   MA  02111-1307  USA
#
#
#   Sun Industry Standards Source License Version 1.1
#   =================================================
#   The contents of this file are subject to the Sun Industry Standards
#   Source License Version 1.1 (the "License"); You may not use this file
#   except in compliance with the License. You may obtain a copy of the
#   License at http://www.openoffice.org/license.html.
#
#   Software provided under this License is provided on an "AS IS" basis,
#   WITHOUT WARRUNTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
#   WITHOUT LIMITATION, WARRUNTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
#   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
#   See the License for the specific provisions governing your rights and
#   obligations concerning the Software.
#
#   The Initial Developer of the Original Code is: Sun Microsystems, Inc..
#
#   Copyright: 2000 by Sun Microsystems, Inc.
#
#   All Rights Reserved.
#
#   Contributor(s): _______________________________________
#
#
#
#*************************************************************************
BEGIN { global_found = "false" }
/[ \t]*local:/ { global_found = "false" }
/^[ \t]*$/ { next }
global_found == "true"  { print $0 }
/[ \t]*global:/ { global_found = "true" }


Fixed indentation

Fixed indentation

BEGIN { FS="," }
{
    num_fields = csv_parse($0, row, ",", "\"", "''", "\\n", 1);
    # get header row names
    if (NR == 1) {
        num_fields = csv_parse($0, col, ",", "\"", "''", "\\n", 1);
    }
    # process every other row
	else {
        # start with select text
		printf "%s", "SELECT "

        # iterate each column value
        for (i = 1; i<=num_fields; i++) {
            printf "%s", "'" row[i] "' AS '" col[i] "'"

            # add a comma except for last row
            if (i < num_fields) printf "%s", ", "
        }

        # nlines is the number of lines in the file
        # so that we know when not to union
    	if (NR != nlines) print " UNION ALL"
        else print "" # end with new line
	}
}

########################### AWK CSV Parser ###########################
#                                                                    #
#      ********** This file is in the public domain. **********      #
#                                                                    #
# Use this source in any way you wish.                               #
# Feedback and bug reports would be appreciated.                     #
# As would a note about what how you are using it.                   #
#                                                                    #
# For more information email LoranceStinson+csv@gmail.com.           #
# Or see http://lorance.freeshell.org/csv/                           #
#                                                                    #
######################################################################
function csv_parse(string,csv,sep,quote,escape,newline,trim, fields,pos,strtrim) {
    if (length(string) == 0) return 0
    string = sep string
    fields = 0
    while (length(string) > 0) {
        if (trim && substr(string, 2, 1) == " ") {
            if (length(string) == 1) return fields
            string = substr(string, 2)
            continue
        }
        strtrim = 0
        if (substr(string, 2, 1) == quote) {
            pos = 2
            do {
                pos++
                if (pos != length(string) &&
                    substr(string, pos, 1) == escape &&
                    index(quote escape, substr(string, pos + 1, 1)) != 0) {
                    string = substr(string, 1, pos - 1) substr(string, pos + 1)
                } else if (substr(string, pos, 1) == quote) {
                    strtrim = 1
                } else if (pos >= length(string)) {
                    if (newline == -1) {
                        return -1
                    } else if (newline) {
                        if (getline == -1) return -4
                        string = string newline $0
                    }
                }
            } while (pos < length(string) && strtrim == 0)
            if (strtrim == 0) {
                return -3
            }
        } else {
            if (length(string) == 1 || substr(string, 2, 1) == sep) {
                fields++
                csv[fields] = ""
                if (length(string) == 1) return fields
                string = substr(string, 2)
                continue
            }
            pos = index(substr(string, 2), sep)
            if (pos == 0) {
                fields++
                csv[fields] = substr(string, 2)
                return fields
            }
        }
        if (trim && pos != (length(string) + strtrim) && substr(string, pos + strtrim, 1) == " ") {
            trim = strtrim
            while (pos < length(string) && substr(string, pos + trim, 1) == " ") {
                trim++
            }
            string = substr(string, 1, pos + strtrim - 1) substr(string,  pos + trim)
            if (!strtrim) {
                pos -= trim
            }
        }
        if ((pos != length(string) && substr(string, pos + 1, 1) != sep)) {
            return -4
        }
        fields++
        csv[fields] = substr(string, 2 + strtrim, pos - (1 + strtrim * 2))
        if (pos == length(string)) {
            return fields
        } else {
            string = substr(string, pos + 1)
        }
    }
    return fields
}
function csv_create (csv,fields,sep,quote,escape,level, field,pos,string) {
    sep     = (sep ? sep : ",")
    quote   = (quote ? quote : "\"")
    escape  = (escape ? escape : "\"")
    level   = (level ? level : 0)
    string = ""
    for (pos = 1; pos <= fields; pos++) {
        field = csv[pos]
        if (field) {
            if (level == 0) {
                string = string csv_escape_string(field, quote, escape, quote escape)
            } else if ((level >= 2) ||
                       (level == 1 && field !~ /^-*[0-9.][0-9.]*$/)) {
                string = string quote csv_escape_string(field, "", escape, quote escape) quote
            } else {
                string = string field
            }
        } else if (level == 3) {
            string = string quote quote
        }
        if (pos < fields) string = string sep
    }
    return string
}
function csv_err (number) {
    if (number == -1) {
        return "More data expected."
    } else if (number == -2) {
        return "Unable to read the next line."
    } else if (number == -3) {
        return "Missing end quote."
    } else if (number == -4) {
        return "Missing separator."
    }
}
function csv_escape_string (string,quote,escape,special, pos,prev,char,csv) {
    prev = 1
    csv = ""
    for (pos = 1; pos < length(string) + 1; pos++) {
        char = substr(string, pos, 1)
        if (index(special, char) > 0) {
            if (pos == 1) {
                csv = escape char
            } else {
                csv = csv substr(string, prev, (pos - prev)) escape char
            }
            prev = pos + 1
        }
    }
    if (prev != pos) {
        csv = csv substr(string, prev)
    }
    if (quote && string != csv) {
        return quote csv quote
    } else {
        return csv
    }
}


add processing for twiki

add processing for twiki

BEGIN {
    heading = 0
}

hunt && /class="section_anchor">/ {
    hier[heading] = $0
    sub(/<\/a>/, "", hier[heading])
    sub(/<\/a>/, "", hier[heading])

    if (heading == 2)
    {
      here = "⋅ " hier[heading]
    }
    else if (heading == 3)
    {
      here = "– " hier[heading]
    }
    else if (heading >= 4)
    {
      here = "— " hier[heading]
    }
    else
    {
      here = hier[heading]
    }

    if (slide) print "
"
    print "
"
    slide = 1
    if (heading > 1) {
      print "
" here "
"
    }
    for (i=1; i < heading; ++i) {
      print "<h" i " style='color: #C0C0C0;'>" hier[i] "</h" i ">"
    }
    print "<h" heading ">" hier[heading]
    hunt = 0
    next
}

## this is for twiki conventions
hunt && heading && /^<a\ name="/ {
    hier[heading] = $0
    sub(/<\/a>/, "", hier[heading])

    if (heading == 2)
    {
      here = "⋅ " hier[heading]
    }
    else if (heading == 3)
    {
      here = "– " hier[heading]
    }
    else if (heading >= 4)
    {
      here = "— " hier[heading]
    }
    else
    {
      here = hier[heading]
    }

    if (slide) print "
"
    print "
"
    slide = 1
    if (heading > 1) {
      print "
" here "
"
    }
    for (i=1; i < heading; ++i) {
      print "<h" i " style='color: #C0C0C0;'>" hier[i] "</h" i ">"
    }
    print "<h" heading ">" hier[heading]
    hunt = 0
    next
}

/
/ {
    heading = 1
    hunt = 1
    next
}

/<\/h[1-9]>/ {
    heading = 0
    print
    next
}

/
/ && heading == 0 {
    heading = 2
    hunt = 1
    next
}

/
/ && heading == 0 {
    heading = 3
    hunt = 1
    next
}

/
/ && heading == 0 {
    heading = 4
    hunt = 1
    next
}

{
  gsub(/
/, "\n&\n")
  print
}

END {
    if (slide) print "
"
}

BEGIN {
    heading = 0
}

hunt && /class="section_anchor">/ {
    hier[heading] = $0
    sub(/<\/a>/, "", hier[heading])
    sub(/<\/a>/, "", hier[heading])

    if (heading == 2)
    {
      here = "⋅ " hier[heading]
    }
    else if (heading == 3)
    {
      here = "– " hier[heading]
    }
    else if (heading >= 4)
    {
      here = "— " hier[heading]
    }
    else
    {
      here = hier[heading]
    }

    if (slide) print "
"
    print "
"
    slide = 1
    if (heading > 1) {
      print "
" here "
"
    }
    for (i=1; i < heading; ++i) {
      print "<h" i " style='color: #C0C0C0;'>" hier[i] "</h" i ">"
    }
    print "<h" heading ">" hier[heading]
    hunt = 0
    next
}

/
/ {
    heading = 1
    hunt = 1
    next
}

/<\/h[1-9]>/ {
    heading = 0
    print
    next
}

/
/ && heading == 0 {
    heading = 2
    hunt = 1
    next
}

/
/ && heading == 0 {
    heading = 3
    hunt = 1
    next
}

/
/ && heading == 0 {
    heading = 4
    hunt = 1
    next
}

{
  gsub(/
/, "\n&\n")
  print
}

END {
    if (slide) print "
"
}


Make convenience init's public

Make convenience init's public

#!/usr/bin/awk
#
# Patch the generated wrapper Swift code to handle special cases
#
BEGIN { depr_init = 0 ; comment = 0 ; slist = 0 }
/open .* ColorSelection/ { depr_init = 1 }
/public .* ColorSelection/ { depr_init = 1 }
/public .* HSV/ { depr_init = 1 }
/open .* HSV/ { depr_init = 1 }
/open .* HSV/ { depr_init = 1 }
/func getColumnHeaderCells/ { comment = 1 }
/func getRowHeaderCells/ { comment = 1 }
/^[^ ]/ { slist = 0 }
/ UnsafeMutablePointer<GSList>! {/ {
	slist = 1
	gsub("UnsafeMutablePointer.GSList..", "SListRef!")
}
/return cast.rv.$/ {
	if (slist) {
		gsub("cast.rv.", "rv.map { SListRef($0) }")
	}
}
/cast.newValue./ {
	if (slist) {
		gsub("cast.newValue.", "newValue.map { $0.ptr }")
		slist = 0
	}
}
/^    }$/ { slist = 0 }
/ init.. {/ {
	if (depr_init) {
		printf("@available(*, deprecated) ")
		depr_init = 0
	}
}
/ init. title:/ {
	if (depr_init) {
		printf("@available(*, deprecated) ")
		depr_init = 0
	}
}
/^open class RadioButton:/ {
	print
	print "    /// Convenience constructor for creating a RadioButton with a text label,"
	print "    /// creating a new group."
	print "    ///"
	print "    /// - Parameter label: the label to use for the button"
	print "    public convenience init(label: UnsafePointer<gchar>) {"
	print "        let rv = gtk_radio_button_new_with_label(nil, label)"
	print "        self.init(cast(rv))"
	print "    }"
	print ""
	print "    /// Convenience constructor for creating a RadioButton with a text label"
	print "    /// that contains menomics creates a new group.  Underscores in `label`"
	print "    /// indicate the mnemonic for the button."
	print "    ///"
	print "    /// - Parameter label: the label (including mnemonic) to use for the button"
	print "    public convenience init(mnemonic label: UnsafePointer<gchar>) {"
	print "        let rv = gtk_radio_button_new_with_mnemonic(nil, label)"
	print "        self.init(cast(rv))"
	print "    }"
	print ""
	next
}
/^open class RadioMenuItem:/ {
	print
	print "    /// Convenience constructor for creating a RadioMenuItem with a text label,"
	print "    /// creating a new group."
	print "    ///"
	print "    /// - Parameter label: the label to use for the button"
	print "    public convenience init(label: UnsafePointer<gchar>) {"
	print "        let rv = gtk_radio_menu_item_new_with_label(nil, label)"
	print "        self.init(cast(rv))"
	print "    }"
	print ""
	print "    /// Convenience constructor for creating a RadioMenuItem with a text label"
	print "    /// that contains menomics and creates a new group.  Underscores in `label`"
	print "    /// indicate the mnemonic for the button."
	print "    ///"
	print "    /// - Parameter label: the label (including mnemonic) to use for the button"
	print "    public convenience init(mnemonic label: UnsafePointer<gchar>) {"
	print "        let rv = gtk_radio_menu_item_new_with_mnemonic(nil, label)"
	print "        self.init(cast(rv))"
	print "    }"
	print ""
	next
}
/^open class RadioToolButton:/ {
	print
	print "    /// Convenience constructor for creating a RadioToolButton group."
	print "    public convenience init() {"
	print "        let rv = gtk_radio_tool_button_new(nil)"
	print "        self.init(cast(rv))"
	print "    }"
	print ""
	next
}
// {
	if (comment) {
		printf("// ")
	}
	print
}
/^    }$/ { comment = 0 }

#!/usr/bin/awk
#
# Patch the generated wrapper Swift code to handle special cases
#
BEGIN { depr_init = 0 ; comment = 0 ; slist = 0 }
/open .* ColorSelection/ { depr_init = 1 }
/public .* ColorSelection/ { depr_init = 1 }
/public .* HSV/ { depr_init = 1 }
/open .* HSV/ { depr_init = 1 }
/open .* HSV/ { depr_init = 1 }
/func getColumnHeaderCells/ { comment = 1 }
/func getRowHeaderCells/ { comment = 1 }
/^[^ ]/ { slist = 0 }
/ UnsafeMutablePointer<GSList>! {/ {
	slist = 1
	gsub("UnsafeMutablePointer.GSList..", "SListRef?")
}
/return cast.rv.$/ {
	if (slist) {
		gsub("cast.rv.", "rv.map { SListRef($0) }")
	}
}
/cast.newValue./ {
	if (slist) {
		gsub("cast.newValue.", "newValue.map { $0.ptr }")
		slist = 0
	}
}
/^    }$/ { slist = 0 }
/ init.. {/ {
	if (depr_init) {
		printf("@available(*, deprecated) ")
		depr_init = 0
	}
}
/ init. title:/ {
	if (depr_init) {
		printf("@available(*, deprecated) ")
		depr_init = 0
	}
}
/^open class RadioButton:/ {
	print
	print "    /// Convenience constructor for creating a RadioButton with a text label,"
	print "    /// creating a new group."
	print "    ///"
	print "    /// - Parameter label: the label to use for the button"
	print "    convenience init(label: UnsafePointer<gchar>) {"
	print "        let rv = gtk_radio_button_new_with_label(nil, label)"
	print "        self.init(cast(rv))"
	print "    }"
	print ""
	print "    /// Convenience constructor for creating a RadioButton with a text label"
	print "    /// that contains menomics creates a new group.  Underscores in `label`"
	print "    /// indicate the mnemonic for the button."
	print "    ///"
	print "    /// - Parameter label: the label (including mnemonic) to use for the button"
	print "    convenience init(mnemonic label: UnsafePointer<gchar>) {"
	print "        let rv = gtk_radio_button_new_with_mnemonic(nil, label)"
	print "        self.init(cast(rv))"
	print "    }"
	print ""
	next
}
/^open class RadioMenuItem:/ {
	print
	print "    /// Convenience constructor for creating a RadioMenuItem with a text label,"
	print "    /// creating a new group."
	print "    ///"
	print "    /// - Parameter label: the label to use for the button"
	print "    convenience init(label: UnsafePointer<gchar>) {"
	print "        let rv = gtk_radio_menu_item_new_with_label(nil, label)"
	print "        self.init(cast(rv))"
	print "    }"
	print ""
	print "    /// Convenience constructor for creating a RadioMenuItem with a text label"
	print "    /// that contains menomics and creates a new group.  Underscores in `label`"
	print "    /// indicate the mnemonic for the button."
	print "    ///"
	print "    /// - Parameter label: the label (including mnemonic) to use for the button"
	print "    convenience init(mnemonic label: UnsafePointer<gchar>) {"
	print "        let rv = gtk_radio_menu_item_new_with_mnemonic(nil, label)"
	print "        self.init(cast(rv))"
	print "    }"
	print ""
	next
}
/^open class RadioToolButton:/ {
	print
	print "    /// Convenience constructor for creating a RadioToolButton group."
	print "    convenience init() {"
	print "        let rv = gtk_radio_tool_button_new(nil)"
	print "        self.init(cast(rv))"
	print "    }"
	print ""
	next
}
// {
	if (comment) {
		printf("// ")
	}
	print
}
/^    }$/ { comment = 0 }


Remove no longer needed doxygen-related awk functions. (dm)

git-svn-id: 30a5f035a20f1bc647618dbad7eea2a951b61b7c@2834 91a5dbb7-01b9-0310-9b5f-b28072856b6e

###############################################################################
# BRLTTY - A background process providing access to the console screen (when in
#          text mode) for a blind person using a refreshable braille display.
#
# Copyright (C) 1995-2006 by The BRLTTY Developers.
#
# BRLTTY comes with ABSOLUTELY NO WARRANTY.
#
# This is free software, placed under the terms of the
# GNU General Public License, as published by the Free Software
# Foundation.  Please see the file COPYING for details.
#
# Web Page: http://mielke.cc/brltty/
#
# This software is maintained by Dave Mielke <dave@mielke.cc>.
###############################################################################

BEGIN {
  commandCount = 0
  keyCount = 0
}

/^ *BRL_CMD_/ {
  brlCommand(substr($1, 9), $1, commandCount++, getComment($0))
  next
}

/#define[ \t]*BRL_BLK_/ {
  brlBlock(substr($2, 9), $2, getDefineValue(), getComment($0))
  next
}

/^ *BRL_KEY_/ {
  gsub(",", "", $1)
  key = tolower(substr($1, 9))
  gsub("_", "-", key)
  brlKey(substr($1, 9), $1, keyCount++, "simulate pressing the " key " key")
  next
}

/#define[ \t]*BRL_FLG_/ {
  brlFlag(substr($2, 9), $2, getDefineValue(), getComment($0))
  next
}

/#define[ \t]*BRL_DOT/ {
  brlDot(substr($2, 8), $2, getDefineValue(), getComment($0))
  next
}

function writeHeaderPrologue(symbol, copyrightFile) {
  writeCopyright(copyrightFile)

  headerSymbol = symbol
  print "#ifndef " headerSymbol
  writeMacroDefinition(headerSymbol)
  print ""

  print "#ifdef __cplusplus"
  print "extern \"C\" {"
  print "#endif /* __cplusplus */"
  print ""
}

function writeCopyright(file) {
  if (length(file) > 0) {
    while (getline line <file == 1) {
      if (match(line, "^ */\\* *$")) {
        print line

        while (getline line <file == 1) {
          print line
          if (match(line, "^ *\\*/ *$")) break
        }

        print ""
        break
      }
    }
  }
}

function writeHeaderEpilogue() {
  print ""
  print "#ifdef __cplusplus"
  print "}"
  print "#endif /* __cplusplus */"

  print ""
  print "#endif /* " headerSymbol " */"
}

function writeMacroDefinition(name, definition, help) {
  statement = "#define " name
  if (length(definition) > 0) statement = statement " " definition

  if (length(help) > 0) print makeDoxygenComment(help)
  print statement
}

function getComment(line) {
  if (!match(line, "/\\*.*\\*/")) return ""
  line = substr(line, RSTART+2, RLENGTH-4)

  match(line, "^\\** *")
  line = substr(line, RLENGTH+1)

  match(line, " *$")
  return substr(line, 1, RSTART-1)
}

function getDefineValue() {
  if ($3 !~ "^\\(") return getNormalizedConstant($3)
  if (match($0, "\\([^)]*\\)")) return substr($0, RSTART, RLENGTH)
  return ""
}

function getNormalizedConstant(value) {
   if (value ~ "^UINT64_C\\(.+\\)$") value = substr(value, 10, length(value)-10)
   return value
}

function makeDoxygenComment(text) {
  return "/** " text " */"
}

function beginDoxygenFile() {
  print "/** \\file"
  print " */"
  print ""
}

function getBrlapiKeyName(name) {
  if (name == "ENTER") return "LINEFEED"
  if (name ~ /^CURSOR_/) return substr(name, 8)
  return name
}

###############################################################################
# BRLTTY - A background process providing access to the console screen (when in
#          text mode) for a blind person using a refreshable braille display.
#
# Copyright (C) 1995-2006 by The BRLTTY Developers.
#
# BRLTTY comes with ABSOLUTELY NO WARRANTY.
#
# This is free software, placed under the terms of the
# GNU General Public License, as published by the Free Software
# Foundation.  Please see the file COPYING for details.
#
# Web Page: http://mielke.cc/brltty/
#
# This software is maintained by Dave Mielke <dave@mielke.cc>.
###############################################################################

BEGIN {
  commandCount = 0
  keyCount = 0
}

/^ *BRL_CMD_/ {
  brlCommand(substr($1, 9), $1, commandCount++, getComment($0))
  next
}

/#define[ \t]*BRL_BLK_/ {
  brlBlock(substr($2, 9), $2, getDefineValue(), getComment($0))
  next
}

/^ *BRL_KEY_/ {
  gsub(",", "", $1)
  key = tolower(substr($1, 9))
  gsub("_", "-", key)
  brlKey(substr($1, 9), $1, keyCount++, "simulate pressing the " key " key")
  next
}

/#define[ \t]*BRL_FLG_/ {
  brlFlag(substr($2, 9), $2, getDefineValue(), getComment($0))
  next
}

/#define[ \t]*BRL_DOT/ {
  brlDot(substr($2, 8), $2, getDefineValue(), getComment($0))
  next
}

function writeHeaderPrologue(symbol, copyrightFile) {
  writeCopyright(copyrightFile)

  headerSymbol = symbol
  print "#ifndef " headerSymbol
  writeMacroDefinition(headerSymbol)
  print ""

  print "#ifdef __cplusplus"
  print "extern \"C\" {"
  print "#endif /* __cplusplus */"
  print ""
}

function writeCopyright(file) {
  if (length(file) > 0) {
    while (getline line <file == 1) {
      if (match(line, "^ */\\* *$")) {
        print line

        while (getline line <file == 1) {
          print line
          if (match(line, "^ *\\*/ *$")) break
        }

        print ""
        break
      }
    }
  }
}

function writeHeaderEpilogue() {
  print ""
  print "#ifdef __cplusplus"
  print "}"
  print "#endif /* __cplusplus */"

  print ""
  print "#endif /* " headerSymbol " */"
}

function writeMacroDefinition(name, definition, help) {
  statement = "#define " name
  if (length(definition) > 0) statement = statement " " definition

  if (length(help) > 0) print makeDoxygenComment(help)
  print statement
}

function getComment(line) {
  if (!match(line, "/\\*.*\\*/")) return ""
  line = substr(line, RSTART+2, RLENGTH-4)

  match(line, "^\\** *")
  line = substr(line, RLENGTH+1)

  match(line, " *$")
  return substr(line, 1, RSTART-1)
}

function getDefineValue() {
  if ($3 !~ "^\\(") return getNormalizedConstant($3)
  if (match($0, "\\([^)]*\\)")) return substr($0, RSTART, RLENGTH)
  return ""
}

function getNormalizedConstant(value) {
   if (value ~ "^UINT64_C\\(.+\\)$") value = substr(value, 10, length(value)-10)
   return value
}

function makeDoxygenComment(text) {
  return "/** " text " */"
}

function beginDoxygenFile(brief) {
  print "/** \\file"
  print " * \\brief " brief
  print " */"
  print ""
}

function beginDoxygenGroup(name, brief) {
  print "/** \\defgroup " name " " brief
  print " * @{ */"
  print ""
}

function endDoxygenGroup() {
  print "/** @} */"
  print ""
}

function getBrlapiKeyName(name) {
  if (name == "ENTER") return "LINEFEED"
  if (name ~ /^CURSOR_/) return substr(name, 8)
  return name
}


Don't fail on build warnings

Don't fail on build warnings

# Exit statuses:
#
# 0 - No errors found.
# 1 - Build or test failure. Errors will be logged automatically.
# 2 - Untestable target. Retry with the "build" action.

BEGIN {
    status = 0;
}

{
    print;
    fflush(stdout);
}

/is not valid for Testing/ {
    exit 2;
}

/[0-9]+: (error|warning):/ {
    errors = errors $0 "\n";
}

/(TEST|BUILD) FAILED/ {
    status = 1;
}

END {
    if (length(errors) > 0) {
        print "\n*** All errors:\n" errors;
    }

    fflush(stdout);
    exit status;
}

# Exit statuses:
#
# 0 - No errors found.
# 1 - Build or test failure. Errors will be logged automatically.
# 2 - Untestable target. Retry with the "build" action.

BEGIN {
    status = 0;
}

{
    print;
    fflush(stdout);
}

/is not valid for Testing/ {
    exit 2;
}

/[0-9]+: (error|warning):/ {
    errors = errors $0 "\n";
    status = 1;
}

/(TEST|BUILD) FAILED/ {
    status = 1;
}

END {
    if (length(errors) > 0) {
        print "\n*** All errors:\n" errors;
    }

    fflush(stdout);
    exit status;
}


var/mapr: BUGFIX: avoid infinite loop on empty input

lib/modernish/aux/var/mapr.awk:
- If the input was empty, the awk helper script didn't write the
  expected _Msh_M_NR=RET0 shell assignment, because the NR awk
  variable (number of records) never exceeded 0. This resulted in
  lib/modernish/mdl/aux/mapr.mm calling awk in an infinite loop.
  The fix is to write the assignment regardless of the value of NR.
- While we're at it, do this in a more efficient way, in one line
  instead of five.

# awk script belonging to modernish var/mapr.mm
#
# This converts the input to commands for the shell to 'eval', based
# on parameters inherited from the environment.
#
# --- begin license ---
# Copyright (c) 2018 Martijn Dekker <martijn@inlv.org>, Groningen, Netherlands
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
# --- end license ---

function round8(num) {
	return (num % 8 == 0) ? num : (num - num % 8 + 8);
}

# Avoid writing very long physical lines of shell code. Some shells on old systems
# can't deal with physical lines exceeding the minimum guaranteed SIZE_MAX==65535.
function printsh(arg) {
	shlen += length(arg);
	if (shlen >= 65533) {	# SIZE_MAX minus backslash minus linefeed
		print "\\\n";	# line continuation
		shlen = length(arg);
	}
	print arg;
}

BEGIN {
	RS = ENVIRON["_Msh_Mo_d"];

	# Some awk versions need a dummy calculation to convert from string to number.
	opt_s = ENVIRON["_Msh_Mo_s"] + 0;
	opt_n = ENVIRON["_Msh_Mo_n"] + 0;
	opt_c = ENVIRON["_Msh_Mo_c"] + 0;
	opt_m = ENVIRON["_Msh_Mo_m"] + 0;
	arg_max = ENVIRON["_Msh_ARG_MAX"] + 0;

	L_cmd = 0;	# count total length of fixed arguments in command line
	for (i=1; i<ARGC; i++) {
		if (opt_m) {
			L_cmd += length(ARGV[i]) + 1;
		} else {
			# macOS seems to need special argument size aligning to avoid a buffer overflow.
			L_cmd += round8(length(ARGV[i]) + 1) + 8;
		}
	}
	ARGC=1;		# nuke arguments so awk won't take them as input files

	c = 0;		# count number of arguments per command invocation
	L = L_cmd;	# count total argument length per command invocation
	tL = 0;		# count total argument length per batch of commands
	cont = 0;	# flag for continuing with multiple awk invocations

}

NR == 1 {
	NR = ENVIRON["_Msh_M_NR"] + 0;	# number of records: inherit from previous batches

	ORS = "";			# no automatic output record separation
	shlen = 0;			# count length of physical line of shellquoted arguments
	printsh("\"$@\" ");		# print fixed command line argument(s)
}

NR <= opt_s {
	next;
}

opt_n && NR > opt_n + opt_s {
	exit 0;
}

# main:
{
	if (opt_m) {
		L += length($0) + 1;
	} else {
		# macOS seems to need special argument size aligning to avoid a buffer overflow.
		L += round8(length($0) + 1) + 8;
	}

	# Check the counters.
	if ((opt_c && c >= opt_c) || (opt_m ? L >= opt_m : L >= arg_max)) {
		# Try not to process much more than 4 megs of arguments per batch.
		if ((tL += L) >= 4194304) {
			cont = 1;
			exit 0;
		}
		printsh("||_Msh_mapr_ckE \"$@\"||break;\"$@\" ");
		c = 0;
		L = L_cmd;
	}

	c++;

	# Output the record as a shell-quoted argument.
	numsegs = split($0, seg, /'/);
	if (numsegs == 0) {
		printsh("'' ");
	} else {
		for (n = 1; n <= numsegs; n++) {
			printsh( ("'") (seg[n]) (n < numsegs ? "'\\'" : "' ") );
		}
	}
}

END {
	if (NR) {
		printsh("||_Msh_mapr_ckE \"$@\"||break");
	}
	print ("\n_Msh_M_NR=") (cont ? NR + 1 : "RET0") ("\n");
}

# awk script belonging to modernish var/mapr.mm
#
# This converts the input to commands for the shell to 'eval', based
# on parameters inherited from the environment.
#
# --- begin license ---
# Copyright (c) 2018 Martijn Dekker <martijn@inlv.org>, Groningen, Netherlands
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
# --- end license ---

function round8(num) {
	return (num % 8 == 0) ? num : (num - num % 8 + 8);
}

# Avoid writing very long physical lines of shell code. Some shells on old systems
# can't deal with physical lines exceeding the minimum guaranteed SIZE_MAX==65535.
function printsh(arg) {
	shlen += length(arg);
	if (shlen >= 65533) {	# SIZE_MAX minus backslash minus linefeed
		print "\\\n";	# line continuation
		shlen = length(arg);
	}
	print arg;
}

BEGIN {
	RS = ENVIRON["_Msh_Mo_d"];

	# Some awk versions need a dummy calculation to convert from string to number.
	opt_s = ENVIRON["_Msh_Mo_s"] + 0;
	opt_n = ENVIRON["_Msh_Mo_n"] + 0;
	opt_c = ENVIRON["_Msh_Mo_c"] + 0;
	opt_m = ENVIRON["_Msh_Mo_m"] + 0;
	arg_max = ENVIRON["_Msh_ARG_MAX"] + 0;

	L_cmd = 0;	# count total length of fixed arguments in command line
	for (i=1; i<ARGC; i++) {
		if (opt_m) {
			L_cmd += length(ARGV[i]) + 1;
		} else {
			# macOS seems to need special argument size aligning to avoid a buffer overflow.
			L_cmd += round8(length(ARGV[i]) + 1) + 8;
		}
	}
	ARGC=1;		# nuke arguments so awk won't take them as input files

	c = 0;		# count number of arguments per command invocation
	L = L_cmd;	# count total argument length per command invocation
	tL = 0;		# count total argument length per batch of commands
	cont = 0;	# flag for continuing with multiple awk invocations

}

NR == 1 {
	NR = ENVIRON["_Msh_M_NR"] + 0;	# number of records: inherit from previous batches

	ORS = "";			# no automatic output record separation
	shlen = 0;			# count length of physical line of shellquoted arguments
	printsh("\"$@\" ");		# print fixed command line argument(s)
}

NR <= opt_s {
	next;
}

opt_n && NR > opt_n + opt_s {
	exit 0;
}

# main:
{
	if (opt_m) {
		L += length($0) + 1;
	} else {
		# macOS seems to need special argument size aligning to avoid a buffer overflow.
		L += round8(length($0) + 1) + 8;
	}

	# Check the counters.
	if ((opt_c && c >= opt_c) || (opt_m ? L >= opt_m : L >= arg_max)) {
		# Try not to process much more than 4 megs of arguments per batch.
		if ((tL += L) >= 4194304) {
			cont = 1;
			exit 0;
		}
		printsh("||_Msh_mapr_ckE \"$@\"||break;\"$@\" ");
		c = 0;
		L = L_cmd;
	}

	c++;

	# Output the record as a shell-quoted argument.
	numsegs = split($0, seg, /'/);
	if (numsegs == 0) {
		printsh("'' ");
	} else {
		for (n = 1; n <= numsegs; n++) {
			printsh( ("'") (seg[n]) (n < numsegs ? "'\\'" : "' ") );
		}
	}
}

END {
	if (NR) {
		printsh("||_Msh_mapr_ckE \"$@\"||break");
		if (cont) {
			print ("\n_Msh_M_NR=") (NR+1) ("\n");
		} else {
			print ("\n_Msh_M_NR=RET0") ("\n");
		}
	}
}


This has been rewritten in perl as parse_structinfo.pl

ok miod@

#	$OpenBSD: parse_structinfo.awk,v 1.1 2009/08/09 23:04:49 miod Exp $
#
# Copyright (c) 2009 Miodrag Vallat.
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#

# This ugly script parses the output of objdump -g in order to extract
# structure layout information, to be used by ddb.
#
# The output of this script is the following static data:
# - for each struct:
#   - its name
#   - its size (individual element size if an array)
#   - the number of elements in the array (1 if not)
#   - its first and last field indexes
# - for each field:
#   - its name
#   - its offset and size
#   - the index of the struct it is member of
# This allows fast struct -> field information retrieval.
#
# To retrieve information from a field size or offset, we also output
# the following reverse arrays:
# - for each offset, in ascending order, a variable length list of field
#   indexes.
# - for each size, in ascending order, a variable length list of field
#   indexes.
#
# The compromise here is that I want to minimize linear searches. Memory
# use is considered secondary, hence the back `pointer' to the struct in the
# fields array.
#
# No attempt is made to share name pointers when multiple fields share
# the same name. Rewriting this script in perl, or any other language
# with hash data structures, would be a good time to add this.

BEGIN {
	depth = 0;
	ignore = 0;
	scnt = 0;	# current struct count
	sidx = -1;	# current struct index
	# field index #0 is used as a sentinel.
	fcnt = 1;	# current field count
	fidx = 0;	# current field index
	ocnt = 0;	# current offset count
	zcnt = 0;	# current size count

}
/^struct / {
	depth = 1;
	sidx = scnt;
	sname[sidx] = $2;
	ssize[sidx] = $6;
	sfieldmin[sidx] = fcnt;
	scnt++;
	#printf("struct %d %s (size %d)\n", sidx, $2, $6);
	next;
}
/^};/ {
	if (depth != 0) {
		depth = 0;
		if (fcnt == sfieldmin[sidx])	# empty struct, ignore it
			scnt--;
		else
			sfieldmax[sidx] = fidx;
	} else
		ignore--;
	next;
}
/{.*}/ {
	# single line enum
	next;
}
/{/ {
	# subcomponent
	if (depth != 0) {
		depth++;
	} else {
		ignore++;
	}
	next;
}
/}/ {
	if (ignore != 0) {
		ignore--;
		next;
	} else {
		depth--;
	}
	if (depth != 1)
		next;
	# FALLTHROUGH
}
/bitsize/ {
	if (ignore != 0)
		next;
	if (depth != 1)
		next;

	# Bitfields are a PITA... From a ddb point of view, we can't really
	# access storage units smaller than a byte.
	# So we'll report all bitfields as having size 0, and the
	# rounded down byte position where they start.
	cursize = int($(NF - 3));
	curoffs = int($(NF - 1) / 8);
	if ((cursize % 8) != 0)
		cursize = 0;
	else
		cursize /= 8;

	# try and gather the field name.
	field = $(NF - 6);
	if (field == "};") {
		# anonymous union. discard it.
		next;
	}
	if (field == "*/);") {
		field = $(NF - 9);	# function pointer
		# remove enclosing braces
		field = substr(field, 2, length(field) - 2);
	}
	colon = index(field, ":");
	if (colon != 0)
		field = substr(field, 1, colon - 1);
	else if (substr(field, length(field), 1) == ";")
		field = substr(field, 1, length(field) - 1);

	while (index(field, "*") == 1)
		field = substr(field, 2);

	# This could be an array. If it is, we need to trim the field
	# name and update its size to a single member size.
	obracket = index(field, "[");
	cbracket = index(field, "]");
	if (obracket != 0) {
		obracket++;
		nitems = substr(field, obracket, cbracket - obracket);
		field = substr(field, 1, obracket - 2);
		cursize /= nitems;
	} else
		nitems = 1;

	fidx = fcnt;
	fname[fidx] = field;
	foffs[fidx] = curoffs;
	fsize[fidx] = cursize;
	fitems[fidx] = nitems;
	fstruct[fidx] = sidx;
	fcnt++;
	#printf("  %s at %d len %d\n", field, curoffs, cursize);

	# Remember size and offset if not found yet

	for (i = 0; i < ocnt; i++)
		if (offs[i] == curoffs)
			break;
	if (i == ocnt) {
		# keep array sorted
		for (i = 0; i < ocnt; i++)
			if (offs[i] > curoffs)
				break;
		if (i < ocnt) {
			for (j = ocnt + 1; j > i; j--)
				offs[j] = offs[j - 1];
		}
		offs[i] = curoffs;
		ocnt++;
	}

	for (i = 0; i < zcnt; i++)
		if (sizes[i] == cursize)
			break;
	if (i == zcnt) {
		# keep array sorted
		for (i = 0; i < zcnt; i++)
			if (sizes[i] > cursize)
				break;
		if (i < zcnt) {
			for (j = zcnt + 1; j > i; j--)
				sizes[j] = sizes[j - 1];
		}
		sizes[i] = cursize;
		zcnt++;
	}
}
END {
	printf("/*\n");
	printf(" * THIS IS A GENERATED FILE.  DO NOT EDIT!\n");
	printf(" */\n\n");

	printf("#include <sys/param.h>\n");
	printf("#include <sys/types.h>\n");
	printf("\n");

	# structure definitions

	printf("struct ddb_struct_info {\n");
	printf("\tconst char *name;\n");
	printf("\tsize_t size;\n");
	printf("\tuint fmin, fmax;\n");
	printf("};\n");

	printf("struct ddb_field_info {\n");
	printf("\tconst char *name;\n");
	printf("\tuint sidx;\n");
	printf("\tsize_t offs;\n");
	printf("\tsize_t size;\n");
	printf("\tuint nitems;\n");
	printf("};\n");

	printf("struct ddb_field_offsets {\n");
	printf("\tsize_t offs;\n");
	printf("\tconst uint *list;\n");
	printf("};\n");

	printf("struct ddb_field_sizes {\n");
	printf("\tsize_t size;\n");
	printf("\tconst uint *list;\n");
	printf("};\n");

	# forward arrays

	printf("#define NSTRUCT %d\n", scnt);
	printf("static const struct ddb_struct_info ddb_struct_info[NSTRUCT] = {\n");
	for (i = 0; i < scnt; i++) {
		printf("\t{ \"%s\", %d, %d, %d },\n",
		    sname[i], ssize[i], sfieldmin[i], sfieldmax[i]);
	}
	printf("};\n\n");

	printf("#define NFIELD %d\n", fcnt);
	printf("static const struct ddb_field_info ddb_field_info[NFIELD] = {\n");
	printf("\t{ NULL, 0, 0, 0 },\n");
	for (i = 1; i < fcnt; i++) {
		printf("\t{ \"%s\", %d, %d, %d, %d },\n",
		    fname[i], fstruct[i], foffs[i], fsize[i], fitems[i]);
	}
	printf("};\n\n");

	# reverse arrays

	printf("static const uint ddb_fields_by_offset[] = {\n");
	w = 0;
	for (i = 0; i < ocnt; i++) {
		cmp = offs[i];
		ohead[i] = w;
		for (f = 1; f < fcnt; f++)
			if (foffs[f] == cmp) {
				if ((w % 10) == 0)
					printf("\t");
				printf("%d, ", f);
				w++;
				if ((w % 10) == 0)
					printf("\n");
			}
		if ((w % 10) == 0)
			printf("\t");
		printf("0, ");
		w++;
		if ((w % 10) == 0)
			printf("\n");
	}
	if ((w % 10) != 0)
		printf("\n");
	printf("};\n\n");

	printf("#define NOFFS %d\n", ocnt);
	printf("static const struct ddb_field_offsets ddb_field_offsets[NOFFS] = {\n");
	for (i = 0; i < ocnt; i++) {
		printf("\t{ %d, ddb_fields_by_offset + %d },\n",
		    offs[i], ohead[i]);
	}
	printf("};\n\n");

	printf("static const uint ddb_fields_by_size[] = {\n");
	w = 0;
	for (i = 0; i < zcnt; i++) {
		cmp = sizes[i];
		zhead[i] = w;
		for (f = 1; f < fcnt; f++)
			if (fsize[f] == cmp) {
				if ((w % 10) == 0)
					printf("\t");
				printf("%d, ", f);
				w++;
				if ((w % 10) == 0)
					printf("\n");
			}
		if ((w % 10) == 0)
			printf("\t");
		printf("0, ");
		w++;
		if ((w % 10) == 0)
			printf("\n");
	}
	if ((w % 10) != 0)
		printf("\n");
	printf("};\n\n");

	printf("#define NSIZES %d\n", zcnt);
	printf("static const struct ddb_field_sizes ddb_field_sizes[NSIZES] = {\n");
	for (i = 0; i < zcnt; i++) {
		printf("\t{ %d, ddb_fields_by_size + %d },\n",
		    sizes[i], zhead[i]);
	}
	printf("};\n");
}