#include <stdio.h> #define QUOTE_COLOR "#ff0000" #define COMMENT_COLOR "#408080" char *Reserved_Words[] = { "ACCESS", "ELSEIF", "PUBLIC", "ADD", "END", "RAISE", "ALL", "ENTRY", "RANGE", "ALTER", "EXCEPTION", "REAL", "AND", "EXCEPTION_INIT", "RECORD", "ANY", "EXISTS", "RELEASE", "ARRAY", "EXIT", "REM", "ARRAYLEN", "FALSE", "RENAME", "AS", "FETCH", "RESOURCE", "ASC", "FLOAT", "RETURN", "ASSERT", "FOR", "REVERSE", "ASSIGN", "FORM", "REVOKE", "AT", "FORMAT", "ROLLBACK", "AUTHORIZATION", "FROM", "ROWID", "BASE_TABLE", "FUNCTION", "ROWLABEL", "BEGIN", "GENERIC", "ROWNUM", "BETWEEN", "GOTO", "ROWTYPE", "BINARY_INTEGER", "GRANT", "RUN", "BODY", "GROUP", "SAVEPOINT", "BOOLEAN", "HAVING", "SCHEMA", "BY", "IDENTIFIED", "SELECT", "CASE", "IF", "SEPARATE", "CHAR", "IN", "SET", "CHAR_BASE", "INDEX", "SIZE", "CHECK", "INDEXES", "SMALLINT", "CLOSE", "INDICATOR", "SPACE", "CLUSTER", "INSERT", "SPOOL", "CLUSTERS", "INTEGER", "SQL", "COLAUTH", "INTERSECT", "SQLCODE", "COLUMN", "INTO", "SQLERRM", "COLUMNS", "IS", "START", "COMMIT", "LEVEL", "STATEMENT", "COMPRESS", "LIKE", "SUBTYPE", "CONNECT", "LIMITED", "TABAUTH", "CONSTANT", "LOOP", "TABLE", "CRASH", "MINUS", "TABLES", "CREATE", "MLSLABEL", "TABLESPACE", "CURRENT", "NATURAL", "TASK", "CURRVAL", "NEW", "TERMINATE", "CURSOR", "NEXTVAL", "THEN", "DATA_BASE", "NOCOMPRESS", "TO", "DATABASE", "NOT", "TRUE", "DATE", "NULL", "TYPE", "DBA", "NUMBER", "UNFORMAT", "DEBUGOFF", "NUMBER_BASE", "UNION", "DEBUGON", "OF", "UNIQUE", "DECIMAL", "ON", "UPDATE", "DECLARE", "OPEN", "USE", "DEFAULT", "OPTION", "VALUES", "DEFINITION", "OR", "VARCHAR", "DELAY", "ORDER", "VARCHAR2", "DELETE", "OTHERS", "VIEW", "DELTA", "OUT", "VIEWS", "DESC", "PACKAGE", "WHEN", "DIGITS", "PARTITION", "WHERE", "DISPOSE", "PCTFREE", "WHILE", "DISTINCT", "POSITIVE", "WITH", "DO", "PRAGMA", "WORK", "DROP", "PRIOR", "XOR", /* Additions by GT: */ "REPLACE", "PROCEDURE", "ELSE", "ELSIF", "PLS_INTEGER", "ROWCOUNT", "ISOPEN", "FORALL", NULL }; int IsReservedWord(char *word) { int i = 0; char *s = word; for (;;) { if (Reserved_Words[i] == NULL) break; if (!strcasecmp(word, Reserved_Words[i++])) return 1; } #ifdef UC_HACK while (*s != '\0') { if ((isalpha(*s)) && (!isupper(*s))) return 0; s += 1; } return 1; #else return 0; #endif } int main(int argc, char **argv) { #define NEXTCH {c = fgetc(stdin); \ pend = fgetc(stdin); \ ungetc(pend, stdin); \ } // surface-level line reconstruction on PL/SQL source, // no deep parsing. Used for conversion to HTML with // 'syntax colouring' (actually lexical colouring) int c = -1, pend = -1, lastch; // start of html printf("<html><head><title></title></head><body><PRE>"); for (;;) { lastch = c; NEXTCH; // C is always the current character, pend is what you will read next. if (c == EOF) { // end of html break; } else if (lastch == '\n' && c == '/' && pend == '\n') { printf("<HR>\n"); } else if (c == '/' && pend == '*') { // handle C comment printf("<font color=%s><i>/*", COMMENT_COLOR); NEXTCH; // C is '*' for (;;) { NEXTCH; if (c == '*' && pend == '/') break; putchar(c); } NEXTCH; // skip / printf("*/</i></font>"); } else if (c == '/' && pend == '/') { // handle C++ comment printf("<font color=%s><i>/", COMMENT_COLOR); for (;;) { if (c == '\n') break; putchar(c); NEXTCH } printf("</i></font>\n"); } else if (c == '-' && pend == '-') { // handle ADA comment printf("<font color=%s><i>", COMMENT_COLOR); for (;;) { if (c == '\n') break; putchar(c); NEXTCH } printf("</i></font>\n"); } else if (c == '\'') { // handle squote literal printf("<font color=%s>'", QUOTE_COLOR); for (;;) { NEXTCH; // how are single quotes escaped in PL/SQL? // - I think by doubling, so fix this! putchar(c); if (c == '\'') break; } printf("</font>"); } else if (c == '"') { // handle dquote literal printf("<font color=%s>\"", QUOTE_COLOR); for (;;) { NEXTCH; // how are double quotes escaped in PL/SQL? // - I think by doubling, so fix this! putchar(c); if (c == '"') break; } printf("</font>"); } else if (isdigit(c)) { // handle number // for now, leave untouched. //printf("<font color=%s><i>\"", NUMBER_COLOR); putchar(c); for (;;) { if (!isdigit(pend)) break; NEXTCH; // How about reals, exponents etc? putchar(c); } //printf("</i></font>"); } else if (isalpha(c)) { // handle keyword or variable char words[1024]; char *word = words; for (;;) { *word++ = c; if (!(isalpha(pend) || isdigit(pend) || (pend == '_') || (pend == '#'))) break; NEXTCH; // What non-std chars are allowed? #? .? _? } *word = '\0'; if (lastch != '.' && IsReservedWord(words)) { printf("<b>%s</b>", words); } else { printf("%s", words); } } else if (c == '&') { printf("&"); } else if (c == '<') { printf("<"); } else if (c == '>') { printf(">"); } else if (c == '\n') { printf("\n"); } else { // output noise char putchar(c); } } printf("</PRE></body></html>\n"); }