Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!cornell!rochester!rutgers!att!alberta!calgary!xenlink!ajfcal!tony From: tony@ajfcal.UUCP (Tony Field) Newsgroups: comp.databases Subject: Re: ORACLE SQLFORMS REPORT TOOL Summary: But not for Xenix 2.2.3 Keywords: ORACLE SQLFORMS TOOL REPORT Message-ID: <54@ajfcal.UUCP> Date: 20 Apr 89 18:58:14 GMT References: <868@hechcx.HEC.HARRIS.COM> <1586@bilpin.UUCP> Organization: Co-Design Systems, Calgary, Ab, Can Lines: 634 > IN ARTICLE <868@hechcx.HEC.HARRIS.COM>, > raym@hechcx.HEC.HARRIS.COM (Ray Morin) WRITES: > > There is supposed to be a RPT program called block.rpt > > that will document block/?and?/form level triggers. If anyone has this > > I would greatly appreciate if they would mail me a copy of it or > > any other useful tool of this type. > > You may well find the following Bourne shell script rather more useful > than any of the RPT programs floating around. I'm posting, rather than > mailing, as I think that it will be of general interest to those using > Oracle with UNIX or similar systems; ... This routine looks very useful, however it does not run under Xenix 2.2.3. Awk gets all confused: 1st pass on myform 2nd pass on myform awk: regular expression too long <====== (((-> Some people keep trying to tell me that Xenix is really Unix.... <-))) Since I don't understand the awk word religion, I cannot correct this problem. (humm. maybe someone will email me gnuawk...). For Xenix users, I offer the following two pieces of c code that does similar things to Jim G's script, however will work under Xenix 2.2.3 against .inp files generated by Oracle version 5.1.17 edition of SqlForms. It does not print out everything: I chose only to print trigger and and commentary information - to keep the confusion level down. There is no Makefile: i simply say "make pform" and "make index" - which works under Xenix 2.2.3. (((I also use source code tab stops set to 4.))) On a slightly different subject, I have a c programme which will allow xenix users to automatically convert .inp files for msdos or for any terminal described in the termcap data base. It is rather lengthy, but if enough interest is shown, I could post it to comp.sources.unix or to comp.sources.misc. It also runs for Oracle 5.1.17 - I haven't yet converted to the new release...... ((ps i hope no one really flames us for post source to what is supposed to be a discussion group for data base theory and management issues. Maybe someone from Oracle Corp. will volunteer to set up a news group for comp.databases.oracle. In some ways, the network is a better method of addressing oracle problems than the excellent oracle hot-line services.)) tony. ----------------- cut here ---------------------- #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh 'pform.c' <<'END_OF_FILE' X/* ta=4 */ X/************************************************************************ X* p f o r m . c * X************************************************************************/ X/* X Scan .inp files. print all triggers in a reasonable format. X X usage: pform f1.inp f2.inp ... X XAuthor: Tony Field ..uunet!utai!calgary!ajfcal!tony X X*/ X X#include X XFILE *fp; Xchar *getline(); Xchar hdr[100], saveline[500]; Xint pushed; X Xmain (argc, argv) Xint argc; Xchar *argv[]; X{ X int i, j; X char line[500]; X char fieldname[200]; X char blockname[200]; X char trigger[200]; X char last; X X X for (i = 1; i < argc; i++) X { X pushed = 0; X *saveline = '\0'; X *line = 0; X *fieldname = 0; X *blockname = 0; X *trigger = 0; X strcpy (blockname, "preform"); X printf ("\n============================ %s ============================\n", argv[i]); X fp = fopen (argv[i], "r"); X X /* get initial comments (preform) */ X X while (getline (line) != NULL) X { X if (strncmp (line, ";Application Title :", 20) == 0) X break; X if (strncmp (line + 10, "--------", 5) == 0) X break; X } X while (getline (line) != NULL) /* initial comments */ X { X if (strncmp (line, ";Application Title :", 20) == 0) X break; X printf ("%s\n", line); X } X X /* Scan for the block and field key words */ X X while (getline (line) != NULL) X { X if (strcmp (line, ";Block name / Description :") == 0) X { X getline (line); X if (strncmp (line, "**", 2) == 0) /* trigger definition */ X { strcpy (trigger, line); X showtrigger (blockname, trigger); X getsql (line); X } X else if (*line == '*') /* block name with order by clause */ X { X strcpy (blockname, line + 1); X trimat (blockname, '/'); /* eliminate the description */ X showblock (blockname); X skip (line, 1); /* skip the ;...: line */ X printf ("\n"); X fetch_and_display (line); X } X else /* block name */ X { X strcpy (blockname, line); X trimat (blockname, '/'); /* eliminate description */ X showblock (blockname); X } X } X X else if (strcmp (line, ";Field name :") == 0) X { X getline (line); X if (*line == '*') /* is block level trigger?*/ X { X strcpy (trigger, line); X showtrigger (blockname, trigger); X getsql (line); X } X else X { X strcpy (fieldname, line); X if (*fieldname) X { printf ("Field: %s\n", fieldname); X gathersql (blockname, fieldname, line); X } X } X } X } X fclose (fp); X } X} X X/**************************************************************************** X* trim (s) * X* Trim trailing blanks and \r\n from a line * X****************************************************************************/ X Xtrim (s) Xchar *s; X{ char last; X X last = '\0'; X while (*s) X { if (*s < ' ') X { *s = '\0'; X return ((int) last); X } X else X { last = *s++; X } X } X return ((int) last); X} X X X/**************************************************************************** X* trimat (name, c) * X* Truncate a line. Replace the found character 'c' with a null. * X****************************************************************************/ X Xtrimat (name,c) Xchar *name, c; X{ X while (*name) X { if (*name == c) X { *name = '\0'; X break; X } X name++; X } X} X X/**************************************************************************** X* skip (line, n) * X* Skip n lines. If the first character of a line is a $ then print the * X* line. (it is a label in the triggers). * X****************************************************************************/ X Xskip (line, n) Xchar *line; Xint n; X{ while (n--) X { getline (line); X if (*line == '$') X printf (" %s\n", line); X } X} X X/**************************************************************************** X* fetch_and_display (line) * X* Display all lines up to the first line that is fully blank or has * X* a / as the first character. This is used to display an SQL trigger. * X****************************************************************************/ X Xfetch_and_display (line) Xchar *line; X{ X while (getline (line) != NULL) X { X if (*line == '/' || *line == '\0') X break; X if (*line == ';') X printf ("%s\n", line); X else X printf (" %s\n", line); X } X return ((int) *line); X} X X X/**************************************************************************** X* showblock (blockname) * X* Display the name of the block in a bold fashion. * X****************************************************************************/ X Xshowblock (blockname) Xchar *blockname; X{ X if (*blockname == '\0') X return; X printf ("\n\n<<<<<<<<<<<<<<<< %s >>>>>>>>>>>>>>>>>\n", blockname); X} X X X/**************************************************************************** X* showtrigger (ref, trigger) * X* Display a trigger with an arrow * X****************************************************************************/ X Xshowtrigger (ref, trigger) Xchar *ref; Xchar *trigger; X{ X printf ("\n--> %s.%s\n", ref, trigger); X} X X/**************************************************************************** X* getline (line) * X* Get the next line from the disk. If there was a line pushed onto the * X* 'save stack', then get that line instead. * X****************************************************************************/ X Xchar *getline (line) Xchar *line; X{ char *how; X X if (pushed) X { X if (*saveline == '%') X return (NULL); X pushed = 0; X strcpy (line, saveline); X return (saveline); X } X X how = fgets (line, 490, fp); X X if (*line == '%') X { strcpy (saveline, "%"); X pushed = 1; X return (NULL); X } X if (how != NULL) X trim (line); X return (how); X} X X X/**************************************************************************** X* pushline (line) * X* Copy the current line onto the one line save stack. * X****************************************************************************/ X Xpushline (line) Xchar *line; X{ X pushed = 1; X strcpy (saveline, line); X} X X X/**************************************************************************** X* getsql (line) * X* Get sql trigger text if the next line contains an ;SQL> directive * X* This is used only for pre-form triggers * X****************************************************************************/ X Xgetsql (line) Xchar *line; X{ X getline (line); X if (strcmp (line, ";SQL>") == 0) X { do X { X fetch_and_display (line); X skip (line, 4); X } while (special_lines (line) == 0); X } X} X X X/**************************************************************************** X* special_lines (line) * X* Get the next line. If it is a 'special sql text line', then return * X* the value '1'. If it not one of these special lines, return '0' * X* Always push the line just read onto the save stack. * X****************************************************************************/ X Xspecial_lines (line) Xchar *line; X{ X getline (line); X if (strcmp (line, ";Block name / Description :") == 0 X || strcmp (line, ";Field name :") == 0 X || strcmp (line, ";SQL>") == 0) X { pushline (line); X return (1); X } X pushline (line); X return (0); X} X X X/**************************************************************************** X* get_lines (line) * X* Read and return the next line if it not a Block or Field special line. * X* If it is, push it back for another read. * X* Used for scanning for sql text in a FIELD trigger. * X****************************************************************************/ X Xget_lines (line) Xchar *line; X{ X if (getline (line) == NULL) X return (1); X if (strcmp (line, ";Block name / Description :") == 0 X || strcmp (line, ";Field name :") == 0) X { pushline (line); X return (1); X } X return (0); X} X X X/**************************************************************************** X* gathersql (blockname, fieldname, line) * X* Get the sql text for FIELD triggers. * X****************************************************************************/ X Xgathersql (blockname, fieldname, line) Xchar *blockname, *fieldname, *line; X{ int v; X X while (get_lines (line) == 0) X { if (strcmp (line, ";SQL>") == 0) X { X if (getline (line) == NULL) /* blank or line with '/' */ X return; X if (*line == '\0') /* blank line means no query */ X continue; X printf ("--> %s\n", line); /* contains trigger type */ X if (getline (line) == NULL) /* then a line with '/' only */ X return; X getline (line); /* and a line with SQL */ X if (strcmp (line, ";SQL>") == 0) X { for ( ;; ) X { X v = display_sql (line); X if (v <= 0) X break; X skip (line, 4); X } X } X } X } X} X X/**************************************************************************** X* display_sql (line) * X* Display all lines up to the first line that is fully blank or has * X* a / as the first character. This is used to display an SQL trigger. * X****************************************************************************/ X Xdisplay_sql (line) Xchar *line; X{ X while (getline (line) != NULL && *line != '%') X { X if (*line == '/' || *line == '\0') X break; X if (*line == ';') X { if (strcmp (line, ";SQL>") == 0) X { pushline (line); X return (-1); X } X else X printf ("%s\n", line); X } X else X printf (" %s\n", line); X } X return ((int) *line); X} END_OF_FILE if test 9367 -ne `wc -c <'pform.c'`; then echo shar: \"'pform.c'\" unpacked with wrong size! fi # end of 'pform.c' fi if test -f 'index.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'index.c'\" else echo shar: Extracting \"'index.c'\" \(3627 characters\) sed "s/^X//" >'index.c' <<'END_OF_FILE' X/* ta=4 */ X/* display the form comment for .inp files and all tables used in blocks X or in list values. optionally display all global variables used X X usage: index [-f] [-n] [-g] f1.inp f2.inp ... X X where: -f = prefix all lines with the .inp file name X -n = prefix all lines with sequential line numbers X -g = show all global variables used X X Note: the line number and file names prefix are useful for X the generation of "sorted cross-references". X XAuthor: Tony Field ..uunet!utai!calgary!ajfcal!tony X*/ X X#include X XFILE *fp; Xchar hdr[100], line[500]; X Xmain (argc, argv) Xint argc; Xchar *argv[]; X{ X int i, j, last, printed, didprint; X int start, prefix, globals, numbers, fnames, cnum; X char name[100], block[100]; X X prefix = globals = numbers = fnames = 0; X X for (start = 1; start < argc; start++) X { X if (*argv[start] == '-') X { X switch (toupper (argv[start][1])) X { X case 'F': X fnames = 1; X break; X case 'G': X globals = 1; X break; X case 'N': X numbers = 1; X default: X break; X } X } X else break; X } X prefix = fnames | numbers; X X *name = '\0'; X for (i = start; i < argc; i++) X { X fp = fopen (argv[i], "r"); X X lead (numbers, i, 0, fnames, argv[i]); X printf ("\n"); X lead (numbers, i, 1, fnames, argv[i]); X printf ("%-15s\n", argv[i]); X didprint = 0; X { *name = *block = '\0'; X cnum = 10; X while (fgets (line, 490, fp) != NULL) X { if (*line == ';' && line[40] == '-') X { while (fgets (line, 490, fp) != NULL) X { X if (strncmp (line, ";Application Title", 18) == 0) X break; X lead (numbers, i, cnum++, fnames, argv[i]); X printf (" %s", line+1); X didprint=1; X } X if (didprint == 0) X { X lead (numbers, i, 10, fnames, argv[i]); X puts (" NO COMMENT"); X } X while (fgets (line, 490, fp) != NULL) X { if (strncmp (line, ";Block name / Description", 20) == 0) X { X fgets (line, 490, fp); X if ((line[0] >= 'A' && line[0] <= 'z') X || (line[0] == '*' && line[1] >= 'A')) X { X j = 0; X while (line[j]) X { X if (line[j] == '/') X { X line[j] = '\0'; X break; X } X j++; X } X lead (numbers, i, 903, fnames, argv[i]); X if (*line == '*') X printf (" Table: %s\n", line + 1); X else X printf (" Table: %s\n", line); X } X } X else if (strncmp (line, ";Lowest value", 12) == 0) X { fgets (line, 490, fp); X if (line[0] == '@') X { X lead (numbers, i, 904, fnames, argv[i]); X printf (" Listv: %s", line + 1); X } X } X else if (globals && tscan (line, "GLOBAL.") >= 0) X { X lead (numbers, i, 905, fnames, argv[i]); X printf (" %s", line); X } X } X } X } X X fclose (fp); X } X } X} X/************************************************ X* t_scan (s,t) * X* char s[],t[]; * X* * X* Index function as defined in K&R * X* Look for string t in s * X* * X* return -1 if t does not exits in s * X* else return array position of first * X* character match * X************************************************/ X X Xtscan (s, t) Xchar s[], t[]; X{ X register int i, j, k; X for (i = 0; s[i] != '\0'; i++) X { for (j = i, k=0; t[k] != '\0' && s[j] == t[k]; j++, k++) X ; X if (t[k] == '\0') X return (i); X } X return (-1); X} X Xlead (numbers, fno, lno, fnames, fn) Xint numbers, fno, lno, fnames; Xchar *fn; X{ X if (numbers) X printf ("%3d %3d ", fno, lno); X if (fnames) X printf ("%-15s ",fn); X} X END_OF_FILE if test 3627 -ne `wc -c <'index.c'`; then echo shar: \"'index.c'\" unpacked with wrong size! fi # end of 'index.c' fi echo shar: End of shell archive. exit 0 -- +------------------------------------ | Tony Field ..uunet!utai!calgary!ajfcal!tony | Co-Design Information Systems Ltd. | Calgary, Alberta, Canada voice: (403) 266-3239