cdesktopenv/cde/admin/IntegTools/dbTools/udbParseLib.awk

766 lines
20 KiB
Awk

# Awk Library file for parsing UDB files
#
function parseUdb() {
# nawk has already read the initial line.
# Tokenize it before doing anything else.
tokenize()
readDefaults(defaults)
# assign hp-ux ".db" file src and link defaults
# if none were designated.
if ( SrcDefault == "" )
SrcDefault = "a_out_location"
if ( LnkDefault == "" )
LnkDefault = "link_source"
if ( TypDefault == "" )
TypDefault = "type"
if ( DestDefault == "" )
DestDefault = "install_target"
if ( ModeDefault == "" )
ModeDefault = "mode"
if ( OwnerDefault == "" )
OwnerDefault = "owner"
if ( GroupDefault == "" )
GroupDefault = "group"
readData()
}
# -------------------------------------------------------------
# readDefaults
# This routine reads the defaults at the front section
# of the universal database and salts the defaults away.
#
# -------------------------------------------------------------
function readDefaults(dflts)
{
if ( DeBug > 0 ) {
Depth++
for ( i=1; i < Depth; i++ )
printf(" ") > DeBugFile
print "Entering function readDefaults" > DeBugFile
}
do {
os = getOS()
if ( osQual != "defaults" )
syntaxError("No defaults for: " BlockToken)
if ( os == BlockToken || os == "default" )
break
skipToToken("}")
} while ( 1 )
fillDefaults()
if ( DeBug > 1 )
print "Skipping remaining defaults" > DeBugFile
# skip remaining default specs
while ( lookAhead() == "{" ) {
# This should be another default spec
# skip it. (watch out for syntax errors)
os = getOS()
if ( osQual != "defaults" )
syntaxError("Expected os:defaults found: \"" os ":" osQual "\"")
if ( os == BlockToken && fileName == FILENAME )
syntaxError("Only one \"defaults\" record allowed per os" )
skipToToken("}");
}
if ( DeBug > 0 ) Depth--
}
# -------------------------------------------------------------
# syntaxError
# bail out
#
# (optionally) mail a message to an administrator if a syntax
# error occurs in a database.
#
# -------------------------------------------------------------
function syntaxError(reason) {
if ( DeBug > 0 ) {
Depth++
for ( i=1; i < Depth; i++ )
printf(" ") > DeBugFile
print "Entering function syntaxError:" > DeBugFile
}
print "Syntax ERROR line: " NR " of file: " FILENAME
if (reason)
print " " reason
system( "rm -f /tmp/SyntaxError" )
system( "touch /tmp/SyntaxError" )
print "Syntax ERROR line: " NR " of file: " FILENAME > "/tmp/SyntaxError"
if (reason)
print " " reason >> "/tmp/SyntaxError"
close( "/tmp/SyntaxError" )
if ( mailTo != "" ) {
system( "mailx -s \"database syntax error\" "mailTo" < /tmp/SyntaxError" )
}
system( "rm -f /tmp/SyntaxError" )
exit 1
}
# -------------------------------------------------------------
# fillDefaults
# This routine reads the defaults in the OS
# defaults section of the database. It saves the defaults
# in the "defaults" awk-style string array.
#
# -------------------------------------------------------------
function fillDefaults() {
if ( DeBug > 0 ) {
Depth++
for ( i=1; i < Depth; i++ )
printf(" ") > DeBugFile
print "Entering function fillDefaults:" > DeBugFile
}
tempDflt = ""
NumEntries = 1
do {
if ( tempDflt != "" ) {
keyword = tempDflt
tempDflt = ""
}
else
keyword = nextToken()
if ( keyword == "}" )
break;
if ( "=" != nextToken())
syntaxError("Keyword: " keyword " not followed by \"=\" ");
tempDflt = nextToken();
if ( lookAhead() == "=" )
defaults[keyword]=""
else {
if ( tempDflt == "<SRC>" ) {
SrcDefault = keyword;
tempDflt = ""
}
if ( tempDflt == "<LNK>" ) {
LnkDefault = keyword;
tempDflt = ""
}
if ( tempDflt == "<TYPE>" ) {
TypDefault = keyword;
tempDflt = "file"
}
if ( tempDflt == "<DEST>" ) {
DestDefault = keyword;
tempDflt = ""
}
if ( tempDflt == "<MODE>" ) {
ModeDefault = keyword;
tempDflt = "0444"
}
if ( tempDflt == "<OWNER>" ) {
OwnerDefault = keyword;
tempDflt = "bin"
}
if ( tempDflt == "<GROUP>" ) {
GroupDefault = keyword;
tempDflt = "bin"
}
defaults[keyword]= tempDflt
tempDflt = ""
}
defOrder[NumEntries++] = keyword;
} while ( 1 )
if ( DeBug > 3 ) {
DBGprintArray(defaults,"defaults")
print "SrcDefault =" SrcDefault > DeBugFile
print "LnkDefault =" LnkDefault > DeBugFile
print "TypDefault =" TypDefault > DeBugFile
}
if ( DeBug > 0 ) Depth--
}
# -------------------------------------------------------------
# getOS
# This routine scans the database for an
# open brace, then a token, then a ":" indicating
# the start of an OS defaults section.
#
# -------------------------------------------------------------
function getOS()
{
if ( DeBug > 0 ) {
Depth++
for ( i=1; i < Depth; i++ )
printf(" ") > DeBugFile
print "Entering function getOS:" > DeBugFile
}
osQual = ""
gotOS = 0
if ( "{" != nextToken() )
syntaxError("Missing initial {")
os = nextToken();
if ( lookAhead() == ":" ) {
nextToken();
osQual= nextToken();
} else
osQual= ""
if ( DeBug > 0 ) Depth--
return os
}
# -------------------------------------------------------------
# nextToken
# parse the incoming data stream into tokens.
#
# -------------------------------------------------------------
function nextToken() {
if ( DeBug > 0 ) {
Depth++
for ( i=1; i < Depth; i++ )
printf(" ") > DeBugFile
print "Entering function nextToken:" > DeBugFile
}
if ( EOF_Reached == 1 )
syntaxError("Premature EOF");
tmpToken=tokens[TK++]
while ( TK > Ntokens || tokens[TK] == ";" ) {
TK++
if ( TK > Ntokens )
if ( newLine() <= 0 ) {
EOF_Reached = 1;
break;
}
}
if ( DeBug > 2 )
print "Returning token: " tmpToken > DeBugFile
if ( DeBug > 0 ) Depth--
return tmpToken
}
# -------------------------------------------------------------
# lookAhead
# return the token at the head of the current list of
# tokens, but do not bump the token count in TK
#
# -------------------------------------------------------------
function lookAhead() {
if ( DeBug > 0 ) {
Depth++
for ( i=1; i < Depth; i++ )
printf(" ") > DeBugFile
print "Entering function lookAhead" > DeBugFile
}
if ( DeBug > 0 ) Depth--
return tokens[TK];
}
# -------------------------------------------------------------
# newLine, tokenize
# read a new line of input and tokenize it.
#
# -------------------------------------------------------------
function newLine() {
if ( DeBug > 0 ) {
Depth++
for ( i=1; i < Depth; i++ )
printf(" ") > DeBugFile
print "Entering function newLine:" > DeBugFile
}
if ( (retval = getline) <= 0 ) {
if ( DeBug > 0 ) Depth--
return retval
}
retval = tokenize()
if ( DeBug > 0 ) Depth--
return retval
}
function tokenize() {
if ( DeBug > 0 ) {
Depth++
for ( i=1; i < Depth; i++ )
printf(" ") > DeBugFile
print "Entering function tokenize:" > DeBugFile
}
# Skip blank/comment lines
while ( NF == 0 || $0 ~ /^[ ]*#/ ) {
if ( (getline) <= 0 ) {
if ( DeBug > 0 ) Depth--
return 0
}
}
#
# Make sure syntactically meaningful characters are surrounded by
# white space. (I gave up on gsub for this purpose).
#
last=1
Str="" # temp string for modified input line
tstStr=$0 # part of input line being tested
newStr=$0 # current input line image with modifications
##########################################################################
# REPLACE THE FOLLOWING LINE WITH A WORK_AROUND FOR A PROBLEM WITH
# THE MATCH FUNCTION FOR THE SUN VERSION OF "nawk"
#
# while ( match(tstStr,"[^\\\][:=}{;]") ) {
#
while ( match(tstStr,"[:=}{;]") ) {
if ( RSTART-1 > 0 && substr(tstStr,RSTART-1,1) != "\\") {
RSTART=RSTART-1
LENGTH=LENGTH+1
} else {
#
# The character was escaped with a backslash.
# Patch things up -- continue testing the rest
# of the line.
#
Str=Str substr($0,last,RSTART+1)
last = last + RSTART + 1
tstStr =substr($0,last)
newStr = Str tstStr
continue;
}
####################### end of workaround ################################
############################################################################
if ( DeBug > 1 ) {
print "Tokenize: Match found in: " tstStr
print "RSTART= " RSTART " ; RLENGTH = " RLENGTH
}
# match found --
# the temp string is now modified to contain:
# 1) all characters up to the match and the first char of match
# 2) blank before the syntactically significant char
# 3) the significant character
# 4) blank following the significant character
Str=Str substr($0,last,RSTART) " " substr($0,last+RSTART,1) " "
last = last + RSTART + 1;
#
# Test remaining part of input line for additional occurances
# of syntactically significant characters.
#
tstStr=substr($0,last)
#
# Our best guess for the new string is the part of the
# input line already tested plus the part yet to be tested.
#
newStr=Str tstStr
}
#
# Check for any instances of syntax chars at the start of the line
#
sub("^[:=}{;]","& ",newStr);
$0 = newStr
#
# allow escaping of significant syntax characters
#
gsub("[\\\][{]","{")
gsub("\\\:",":")
gsub("\\\;",";")
gsub("\\\=","=")
gsub("[\\\][}]","}")
#
# Having insured that interesting chars are surrounded by blanks
# now tokenize the input line.
#
Ntokens = split($0,tokens)
TK = 1
if ( DeBug > 3 )
DBGprintTokens()
if ( DeBug > 0 ) Depth--
return Ntokens
}
function DBGprintTokens()
{
for ( i = 1; i <= Ntokens ; i++ )
print "tokens[" i "] = " tokens[i] > DeBugFile
return 0
}
function DBGprintArray(array,name) {
for ( i in array) {
print name "[" i "] = " array[i] > DeBugFile
}
}
# -------------------------------------------------------------
# skipToToken
# read until the passed in token is encountered
#
# -------------------------------------------------------------
function skipToToken(tok)
{
if ( DeBug > 0 ) {
Depth++
for ( i=1; i < Depth; i++ )
printf(" ") > DeBugFile
print "Entering function skipToToken:" > DeBugFile
}
while ( nextToken() != tok )
;
if ( DeBug > 0 ) Depth--
}
# -------------------------------------------------------------
# readData
#
# -------------------------------------------------------------
function readData() {
if ( DeBug > 0 ) {
Depth++
for ( i=1; i < Depth; i++ )
printf(" ") > DeBugFile
print "Entering function readData" > DeBugFile
}
while ( EOF_Reached == 0 ) {
if ( fileName != FILENAME ) {
if ( DeBug > 1 ) {
print "====>Files Changed" > DeBugFile
print "fileName= " fileName > DeBugFile
print "FILENAME= " FILENAME > DeBugFile
}
fileName = FILENAME
# skip over defaults section of the new file
while ( lookAhead() == "{" ) {
# This should be another default spec
# skip it. (watch out for syntax errors)
os = getOS()
if ( osQual != "defaults" )
syntaxError("Expected os:defaults found: \"" os ":" osQual "\"")
#
# Relax this restriction since we are
# ignoring this defaults record
#if ( os == BlockToken )
# syntaxError("Only one \"defaults\" record allowed per os" )
skipToToken("}");
}
}
if ( getNextRecord(record) > 0 )
PRTREC(record);
# skip remaining os entries for this source
# sorry no error checking.
while ( EOF_Reached == 0 && lookAhead() == "{" )
skipToToken("}")
if ( DeBug > 1 )
print "EOF_Reached = " EOF_Reached > DeBugFile
}
if ( DeBug > 0 ) Depth--
}
# -------------------------------------------------------------
# getNextRecord
#
# this function fills the rec[] array with defaults
#
# then it scans for a block that has a token maching
# BlockToken, or accepts a block with the "default"
# token. The "default" token is not accepted if
# defaults are disallowed.
#
# finally fillRecord is called to read in the lines
# in the block and override the entries in the rec[] array.
#
# -------------------------------------------------------------
function getNextRecord(rec) {
if ( DeBug > 0 ) {
Depth++
for ( i=1; i < Depth; i++ )
printf(" ") > DeBugFile
print "Entering function getNextRecord:" > DeBugFile
}
# fill with defaults
for ( i in defaults )
rec[i] = defaults[i];
do {
src = nextToken()
if ( DeBug > 2 )
print "src=" src > DeBugFile
# Allow special characters to appear in src names if they have been backslashed
# if ( src ~ /[{:=}]/ )
# syntaxError("Invalid source: \"" src "\"");
do {
os = getOS()
if ( DeBug > 1 ) {
print "Got os " os " and qual= " osQual > DeBugFile
print "NR= " NR " : " $0 > DeBugFile
}
if (( os != BlockToken || osQual == "not" ) \
&& ( os != "default" || UseDefaultBlocks != "Y" ) ) {
if ( DeBug > 2)
print "Skipping to end of os rec" > DeBugFile
skipToToken("}");
}
if ( EOF_Reached == 1 || fileName != FILENAME ){
if ( DeBug > 0 ) Depth--
return 0
}
if ( DeBug > 2 )
print "Look Ahead is: " tokens[TK] > DeBugFile
} while ( lookAhead() == "{" )
} while (( os != BlockToken ) && ( os != "default" || UseDefaultBlocks != "Y"))
if ( DeBug > 2)
print "About to call fillRecord" > DeBugFile
fillRecord(rec)
if ( DeBug > 0 ) Depth--
return 1
}
function fillRecord(rec) {
if ( DeBug > 0 ) {
Depth++
for ( i=1; i < Depth; i++ )
printf(" ") > DeBugFile
print "Entering fillRecord:" > DeBugFile
}
tempEntry = ""
do {
if ( tempEntry != "" ) {
keyword = tempEntry;
tempEntry = ""
} else
keyword = nextToken();
if ( keyword == "}" )
break;
if ( "=" != nextToken())
syntaxError("Keyword: " keyword " not followed by \"=\"");
tempEntry = nextToken();
if ( lookAhead() == "=" )
rec[keyword] = ""
else {
rec[keyword] = tempEntry
tempEntry = ""
}
} while (1)
#
# check for source entry
# THIS IMPLIES KNOWLEDGE OF .db FILE ENTRIES!!
if ( DeBug > 2)
print "TYPE= " rec[TypDefault] > DeBugFile
if ( src == "-" )
if ( rec[TypDefault]=="directory" || rec[TypDefault]=="empty_dir")
{
# no source required for a directory
if ( rec[SrcDefault] != "" )
syntaxError(SrcDefault " \"" rec[SrcDefault] "\" specified for a directory.")
if ( rec[LnkDefault] != "" )
syntaxError(LnkDefault " \"" rec[LnkDefault] "\" specfied for a directory.")
rec[SrcDefault] = src;
} else if ( rec["status"] == "---cu-" ) {
# This is used for some reason (X11-SERV.db)
if ( rec[SrcDefault] != "" )
syntaxError( "File: \"" rec["install_target"] "\" with special status: \"---cu-\" should have no source.");
} else
syntaxError("Invalid source: \"" src "\" for type: \"" rec[TypDefault] )
else if ( rec[TypDefault] ~ /link/ )
if ( src ~ /^\// || src ~ /^\./ ) {
if ( rec[SrcDefault] != "")
syntaxError( SrcDefault ": \"" rec[SrcDefault] "\" specified for link: \"" src "\"")
if ( rec[LnkDefault] == "" )
rec[LnkDefault]=src;
} else
syntaxError("Invalid source: \"" src "\" for type: \"" rec[TypDefault] "\"")
else if ( rec[TypDefault] == "file" || rec[TypDefault] == "control" )
rec[SrcDefault] = src;
else
syntaxError("Unrecognized type:\"" rec[TypDefault] "\"")
if ( DeBug > 0 ) Depth--
}
# -------------------------------------------------------------
# printDB
# Print records in ".db" format
# -------------------------------------------------------------
function printDb(rec) {
if ( DeBug > 0 ) {
Depth++
for ( i=1; i < Depth; i++ )
printf(" ") > DeBugFile
print "Entering printDb:" > DeBugFile
}
# NumEntries should be one greater than the number of defaults
# read in.
for ( i = 1; i< NumEntries; i++ ) {
printf("%-40s %s %s\n",defOrder[i], ":",rec[defOrder[i]])
}
print "#"
if ( DeBug > 0 ) Depth--
}
# -------------------------------------------------------------
# printLst
# Print records in ".lst" format
# -------------------------------------------------------------
function printLst(rec) {
if ( DeBug > 0 ) {
Depth++
for ( i=1; i < Depth; i++ )
printf(" ") > DeBugFile
print "Entering printLst:" > DeBugFile
}
if ( rec[TypDefault] ~ /link/ )
Source = LnkDefault
else
Source = SrcDefault
printf("%s %s %s %s %s %s %s %s %s\n",
rec[ DestDefault],
rec[ ModeDefault ],
rec[ Source ],
rec[ TypDefault ],
rec[ OwnerDefault ],
rec[ GroupDefault ],
rec[ "status" ],
rec[ "processor" ],
rec[ "responsible_project" ] )
if ( DeBug > 0 ) Depth--
}
# -------------------------------------------------------------
# printGather
# print records in one of the formats expected by Gather.ksh
# (Jim Andreas print routine).
# -------------------------------------------------------------
function printGather(rec) {
# print "Entering printRecord: "
if (( BlockToken == "hp-ux" ) && ( rec[ "processor" ] != "378" ))
{
if ( index( rec[ "processor" ], Machine ) == 0 )
{
#printf( "skipping %s, Machine %s machines %s\n", src, Machine, rec[ "processor" ] );
return
}
}
if ( action == "toSDD" )
{
if ( rec[ "type" ] == "file" )
{
printf("%s:F:%s:%s:%s:*::\n",
rec[ "install_target" ], rec[ "owner" ],
rec[ "group" ], rec[ "mode" ])
}
}
else if ( action == "toReleaseTree" )
{
if ( ( rec[ "type" ] == "hard_link" ) ||
( rec[ "type" ] == "sym_link" ) ||
( rec[ "type" ] == "file" ) )
{
#
# if this is a link, then fudge a source file for Gather.ksh
# to check on. Really we are linking two dest files together
# so the hack is to get around the check in Gather.ksh
#
if ( ( rec[ "type" ] == "hard_link" ) ||
( rec[ "type" ] == "sym_link" ) )
{
printf( " {s}%s {d}%s\n", "-", rec[ "install_target" ] );
}
else if ( length( src ) > 34 )
printf( " {s}%s {d}%s\n", src, rec[ "install_target" ] );
else
printf( " {s}%-34s {d}%s\n", src, rec[ "install_target" ] );
if ( rec[ "install_rule_name" ] == "c-" )
{
printf( "compress -c < {s}%s > {d}%s\n", src,
rec[ "install_target" ] );
}
else if ( rec[ "type" ] == "sym_link" )
{
printf( "ln -s %s {d}%s\n", src,
rec[ "install_target" ] );
}
else if ( rec[ "type" ] == "hard_link" )
{
printf( "ln {d}%s {d}%s\n", src,
rec[ "install_target" ] );
}
else if ( rec[ "uncompress" ] == "true" )
{
printf( "uncompress -c < {s}%s > {d}%s\n", src,
rec[ "install_target" ] );
}
else if ( length( src ) > 34 )
{
printf( "cp {s}%s {d}%s\n", src,
rec[ "install_target" ] );
}
else
{
printf( "cp {s}%-34s {d}%s\n", src,
rec[ "install_target" ] );
}
printf( "%s %s %s\n", rec[ "owner" ], rec[ "group" ], rec[ "mode" ])
rec[ "install_rule_name" ] = "";
rec[ "uncompress" ] = "";
}
}
else if ( action == "toDeliverArgs" )
{
temp = rec[ "install_target" ];
m = n = index( temp, "/" );
while ( n != 0 )
{
temp = substr( temp, n+1 );
n = index( temp, "/" );
m += n;
}
dirnametarget = substr( rec[ "install_target" ], 1, m-1 );
if ( length( rec[ "install_target" ] ) > 40 )
{
printf("%s -d .%s\n", rec[ "install_target" ], dirnametarget );
}
else
{
printf("%-40s -d .%s\n", rec[ "install_target" ], dirnametarget );
}
}
else if ( action == "toCheckBuild" )
{
# print "Entering printRecord - toCheckBuild: "
#
# skip any link info
#
if ( rec[ "type" ] == "file" )
{
#
# just print the source path for the checker tool
#
printf("%s\n", src );
}
}
else if ( action == "toFileList" )
{
#
# skip any link info
#
if ( rec[ "type" ] == "file" )
{
#
# print the source and install_target for the human person
#
if ( length( src ) > 40 || length( rec[ "install_target" ] ) > 40 )
{
printf("%s -> %s %s\n", src,
rec[ "install_target" ], rec[ "mode" ] );
}
else
{
printf("%-40s -> %-40s %s\n", src,
rec[ "install_target" ], rec[ "mode" ] );
}
}
}
else if ( action == "toTargetList" )
{
#
# skip any link info
#
if ( rec[ "type" ] == "file" )
{
#
# just print the install_target
#
printf("%s\n", rec[ "install_target" ] );
}
}
}