#! /usr/bin/gawk -f # Last edited on 2003-12-20 15:15:40 by hcgl /INTERFACE/ { printf "#ifndef _H\n#define _H\n\n"; next; is_header = 1; } /MODULE/ { gsub(/[;]/, " ", $0); printf ( "#include <" $2 ".h>" ); next; is_header = 0; } # Fix procedure declarations: /PROCEDURE/{ # Read whole procedure header, replacing line breaks by "@" lin = ( "@" $0 ); while (! match(lin, /[)].*[=;]/)) { getline nxt; lin = (lin "@" nxt); } # Ensure that the first argument starts on a new line: lin = gensub(/[(] *([^ @])/, "(@ \\1", "g", lin); # Ensure that each argument starts on a separate line: lin = gensub(/[;]( *[«][^«»]*[»]|) *([^@ «»])/, "; \\1@ \\2", "g", lin); # Ensure that the last argument ends with a ";", too: lin = gensub(/[ @]*[)]/, ";@ )", "g", lin); lin = gensub(/([«][^«»]*[»]) *[;]/, "; \\1", "g", lin); # Remove duplicate ";"s: lin = gensub(/[ ;]+[;]/, ";", "g", lin); # Remove /*OUT*/, /*IN*/, etc. to comment part: lin = gensub(/[«][ (]*(OUT|IN|WORK)[) ]*[»]([^@«»]*)/, "\\2 « (\\1) »", "g", lin); # Turn Default values into comments: lin = gensub(/([:][=][^@;)«»]*)[;]/, "; « (\\1) »", "g", lin); # Merge multiple comments into one: lin = gensub(/[»] *[«]/, " ", "g", lin); # Break multiple argument declarations into single ones: do { tmp = lin; lin = gensub(/[@] *(READONLY *|VAR *|)([A-Za-z_0-9]+) *[,] ([^@:]+)[:] *([][A-Za-z_0-9. ]+)[;]/, \ "@ \\1\\2: \\4;@ \\1\\3: \\4;", "g", lin); } while (tmp != lin) # Replace "VAR ID: TYPE;" by "VAR TYPE ID;", ditto for READONLY lin = gensub(/[@] *(READONLY|VAR) *([A-Za-z_0-9]+) *[:] *([][A-Za-z_0-9. ]+)[;]/, "@ \\1 \\3 \\2;", "g", lin); # Replace "ID: TYPE;" by "TYPE ID;" lin = gensub(/[@] *([A-Za-z_0-9]+) *[:] *([][A-Za-z_0-9. ]+)[;]/, "@ \\2 \\1;", "g", lin); # Move return type to the front: lin = gensub(/PROCEDURE *(.*[)]) *[:] *([][A-Za-z_0-9. ]+) *[=;]*/, "\\2 \\1", "g", lin); lin = gensub(/PROCEDURE *(.*[)]) *[=;]+/, "void \\1", "g", lin); # Replace ";" by "," lin = gensub(/[@]([^«»@]*)[;]/, "@\\1,", "g", lin); # Remove comma after last argument: lin = gensub(/[,]( *[«].*[»]|) *@ *[)]/, " \\1@ )", "g", lin); # Restore ";" at end of header: lin = gensub(/[)] *[,]/, ");", "g", lin); # Replace "@" by line breaks: lin = gensub(/[@]/, "\n", "g", lin); print lin; next; } # Fix WITH statements: / WITH/{ # Get indentation of "WITH": match($0, /^ */); indent = substr($0, 1, RLENGTH); # Read whole WITH header, replacing line breaks by "@" lin = ( "@" $0 ); while (! match(lin, / DO/)) { getline nxt; lin = (lin "@" nxt); } # Ensure that the first item starts on a new line: lin = gensub(/WITH *([^ @])/, ("WITH@" indent " \\1"), "g", lin); # Replace "," by ";" between items: lin = gensub(/[,]( *[«][^«»]*[»]|) *[@]/, ";\\1@", "g", lin); # Ensure that the last argument ends with a ";", too: lin = gensub(/[ @]* DO/, (";@" indent "DO"), "g", lin); lin = gensub(/([«][^«»]*[»]) *[;]/, "; \\1", "g", lin); # Remove duplicate ";"s: lin = gensub(/[ ;]+[;]/, ";", "g", lin); # Replace "ID == EXPR;" by "??? ID = EXPR;" lin = gensub(/[@]( *)([A-Za-z_0-9]+) *[=] *([^@]*)[;]/, "@\\1??? \\2 = \\3;", "g", lin); # Replace "WITH" by "{", delete "DO": lin = gensub(/WITH/, "{ « with »", "g", lin); lin = gensub(/ DO/, " « do »", "g", lin); # Replace "@" by line breaks: lin = gensub(/[@]/, "\n", "g", lin); print lin; next; } # Fix RECORD statements: / RECORD/{ # Get indentation of "RECORD": match($0, /^ */); indent = substr($0, 1, RLENGTH); # Read whole record declaration, replacing line breaks by "@" lin = ( "@" $0 ); while (! match(lin, /END/)) { getline nxt; lin = (lin "@" nxt); } # Ensure that the first field starts on a new line: lin = gensub(/RECORD *([^ @])/, ("RECORD@" indent " \\1"), "g", lin); # Ensure that each field starts on a separate line: lin = gensub(/[;]( *[«][^«»]*[»]|) *([^@ «»])/, "; \\1@ \\2", "g", lin); # Ensure that the last field ends with a ";", too: lin = gensub(/[ @]*END/, (";@" indent "END"), "g", lin); lin = gensub(/([«][^«»]*[»]) *[;]/, "; \\1", "g", lin); # Remove duplicate ";"s: lin = gensub(/[ ;]+[;]/, ";", "g", lin); # Break multiple field declarations into single ones: do { tmp = lin; lin = gensub(/[@] *([A-Za-z_0-9]+) *[,] ([^@:]+)[:] *([][A-Za-z_0-9. ]+)[;]/, \ ("@" indent " \\1: \\3;@" indent " \\2: \\3;"), "g", lin); } while (tmp != lin) # Replace "ID: TYPE;" by "TYPE ID;" lin = gensub(/[@] *([A-Za-z_0-9]+) *[:] *([][A-Za-z_0-9. ]+)[;]/, "@ \\2 \\1;", "g", lin); # Replace "RECORD ... END" by "struct ??? { ... } ???": lin = gensub(/RECORD/, "struct ??? {", "g", lin); lin = gensub(/END/, "} ???", "g", lin); # Replace "@" by line breaks: lin = gensub(/[@]/, "\n", "g", lin); print lin; next; } # Fix variable declarations: /VAR / { # Get indentation of "VAR": match($0, /^ */); indent = substr($0, 1, RLENGTH); # Read VAR declaration: lin = ( "@" $0 ); while (! match(lin, /[;]/)) { getline nxt; lin = (lin " " nxt); } # Break multiple variable declarations into single ones: do { tmp = lin; lin = gensub(/VAR *([A-Za-z_0-9]+) *[,] ([^@:]+)[:] *([][A-Za-z_0-9. ]+)[;]/, \ ("@" indent "VAR \\1: \\3;@" indent "VAR \\2: \\3;"), "g", lin); } while (tmp != lin) # Change "VAR ID: TYPE" into "TYPE ID: lin = gensub(/VAR +([a-zA-Z0-9_, ]+) *[:] *([][A-Za-z_0-9. ]+) *[;]/, "\\2 \\1;", "g", lin); # Replace ":=" by "=": lin = gensub(/[:][=]/, "=", "g", lin); # Replace "@" by line breaks: lin = gensub(/[@]/, "\n", "g", lin); print; next; } # Remove trailing END of module: /^ *END [a-zA-Z_]*[.]/ { if (is_header) { print "\n#endif"; } next; } # Remove FATAL lines: /<* FATAL / { next; } //{ lin = $0; # Remove identifiers after procedure END: lin = gensub(/END ([a-zA-Z0-9_]+) *[;]/, "} « \\1 »", "g", lin); # Fix boolean operators and assignemnt: lin = gensub(/([^<>:])[=]/, "\\1==", "g", lin); lin = gensub(/ # /, " != ", "g", lin); lin = gensub(/[:][=]/, "=", "g", lin); # Replace major keywords and functions: lin = gensub(/\/, "for (", "g", lin); lin = gensub(/\/, "while (", "g", lin); lin = gensub(/\/, "return", "g", lin); lin = gensub(/\ */, "while (1){", "g", lin); lin = gensub(/\/, "}else if ((", "g", lin); lin = gensub(/\/, "if ((", "g", lin); lin = gensub(/\/, "){", "g", lin); lin = gensub(/\/, ")){", "g", lin); lin = gensub(/\/, "}else{", "g", lin); lin = gensub(/\/, "{", "g", lin); lin = gensub(/\/, ";}", "g", lin); lin = gensub(/[<][*] *ASSERT /, "assert(", "g", lin); lin = gensub(/[*][>]/, ");", "g", lin); lin = gensub(/\/, "NULL", "g", lin); lin = gensub(/\/, ") || (", "g", lin); lin = gensub(/\/, ") \&\& (", "g", lin); lin = gensub(/\/, "abs", "g", lin); lin = gensub(/\/, "max", "g", lin); lin = gensub(/\/, "min", "g", lin); print lin; }