Oracle/Pro*Ada/LSE/DEC Ada utility
Date: Fri, 27 Aug 1993 23:49:12 +0200
Message-ID: <H.eg.3V5A2BYqjAQ_at_mbase97.hacktic.nl>
Hi,
a couple of weeks ago I asked whether people would be interested in
the utility I wrote to make Proada work with LSE/VMS/DEC Ada.
A few people were interested, so here goes.
I suspect that PRO*X (X is some language) suffers from the same lack of LSE support, so maybe users of another language can port this utility to that language. If anybody does, please let me know.
The main feature is that you can REVIEW Proada errors in LSE, so you can quickly locate erroneous SQL code, without having to examine the .LIS file and looking up the line number.
Other features:
- precompile a .PAD file in LSE with COMPILE.
- precompile .PAD-file, load&compile generated Ada code. Review
any errors in Proada or Ada compilation with one command: "PRO".
Ada errors will point you to the Ada files, not the .PAD file.
A common mistake is to edit the Ada file, while you should edit the
.PAD file. Therefore the ADA buffers are made Unmodifiable.
How it works:
A filter (written in Ada) translates the .LIS output of proada to
a diagnostics (.DIA) file.
LSE is taught a new language: PROADA, with extension .PAD. The
compilation command is LSE_PROADA.
LSE_PROADA is a DCL commandfile that calls proada, and the filter.
If succesful, it also compiles the generated ADA files.
The command PRO does this compilation, and additionally loads the
generated ADA files into Unmodifiable LSE buffers, you can review
errors in the Ada code as well.
How to instal it:
Call this file "LSE_PROADA.COM", and
install it in your LOGIN.COM as symbol "LSE_PROADA".
Change the [maarten.lse] to the directory containing PAD_DIA.EXE.
------------------------------------cut----------------------
$ set noon
$ device=f$parse("''p1'",,,"DEVICE")
$ directory=f$parse("''p1'",,,"DIRECTORY")
$ name=f$parse("''p1'",,,"NAME")
$ full_directory=device+directory
$ basename=full_directory+name
$ diafile="''basename'.dia"
$ lisfile="''basename'.lis"
$ adafile="''basename'.ada"
$ oradclfile="''basename'.ora_dcl"
$ set def 'full_directory'
$ proada iname='p1' lname='lisfile' sqlcheck=semantics userid=/ ireclen=255 oreclen=255 lreclen=255
$ severity=$severity
$ define/nolog/job proada_pad_file 'p1'
$ define/nolog/job dia_file 'diafile'
$ write sys$output "name ''p1'"
$ define/nolog proada_dia_file 'diafile'
$ define/nolog proada_lis_file 'lisfile'
$ run [maarten.lse]pad_dia
$ write sys$output "proada-severity ''severity'"
$ if 'severity' .ne. 1 then goto einde
$! severity=1=Succes $! try to compile the generated ada files
$ ada /optimize=development 'oradclfile' /diagnostics='diafile'
$ severity=$severity
$ if 'severity' .ne. 1 then goto einde
$ ada /optimize=development 'adafile' /diagnostics='diafile'
$ severity=$severity
$ write sys$output "ada-severity ''severity'"
$ einde:
$ exit 'severity'
------------------------------------cut----------------------
Compile this ada program and call the executable PAD_DIA.EXE. It will be
called from LSE_PROADA.COM.
The program should be easily ported to say, C. If you encounter any
problems please don't hesitate to mail me. Note: this is not the
most beautiful piece of software I've ever written, but it does the job.
------------------------------------cut------------------------ This program converts the 'list' (.lis) output of the pro*ada precompiler -- into a diagnostics (.dia) file.
with text_io; use text_io;
procedure PAD_DIA is
IN_FILE_LOGICAL : constant STRING := "PROADA_LIS_FILE:"; OUT_FILE_LOGICAL : constant STRING := "PROADA_DIA_FILE:"; PAD_SOURCE_LOGICAL : constant STRING := "PROADA_PAD_FILE:";
MAX_DIAGNOSTICS : constant POSITIVE := 30; LIS_FILE : FILE_TYPE; DIA_FILE : FILE_TYPE;
LINE : STRING(1..300);
LENGTH : NATURAL; -- length of line
ERROR_MESSAGE : array (1..20) of STRING(1..200); ERROR_MESSAGE_LENGTH : array (1..20) of NATURAL;NUMBER_OF_ERROR_MESSAGES : NATURAL;
COLUMN_NUMBER : STRING(1..5); COLUMN_NUMBER_LENGTH : NATURAL; SOURCE_LINE_NUMBER : STRING(1..5); SOURCE_LINE_NUMBER_LENGTH : NATURAL;
NUMBER_OF_EMITTED_DIAGNOSTICS : NATURAL := 0; READING_ERROR_MESSAGE : BOOLEAN := FALSE; NOT_FOUND : exception; -- raised by FIND
function FIND( START_AT_POSITION : in POSITIVE;
SEARCH_STRING : in STRING) return POSITIVE is begin
for I in START_AT_POSITION..LENGTH-SEARCH_STRING'LENGTH+1 loop if LINE(I..I+SEARCH_STRING'LENGTH-1) = SEARCH_STRING then return I; end if; end loop; raise NOT_FOUND;
end FIND;
function FIND_NON_NUMERIC( START_AT_POSITION: in POSITIVE)
return POSITIVE is
begin
for I in START_AT_POSITION..LENGTH loop if LINE(I) < '0' or LINE(I) > '9' then return I; end if; end loop; raise NOT_FOUND;
end FIND_NON_NUMERIC;
function ERROR_LIMIT_REACHED return BOOLEAN is begin
return NUMBER_OF_EMITTED_DIAGNOSTICS >= MAX_DIAGNOSTICS; end ERROR_LIMIT_REACHED;
procedure EMIT_NEW_LINE is
begin
NEW_LINE(FILE => DIA_FILE);
end EMIT_NEW_LINE;
procedure EMIT(LINE: in STRING) is
begin
PUT(FILE => DIA_FILE, ITEM => LINE);
end EMIT;
procedure EMIT_LINE(LINE: in STRING) is begin
EMIT(LINE); EMIT_NEW_LINE;
end EMIT_LINE;
procedure EMIT(CHAR : in CHARACTER) is begin
PUT(FILE => DIA_FILE, ITEM => CHAR);
end EMIT;
procedure EMIT_QUOTED_STRING(LINE: in STRING) is
QUOTE : constant CHARACTER := '"';
begin
EMIT(QUOTE); for I in LINE'RANGE loop EMIT(LINE(I)); if LINE(I)=QUOTE then EMIT(QUOTE); -- double it end if; end loop; EMIT(QUOTE);
end EMIT_QUOTED_STRING;
procedure EMIT_DIAGNOSTIC is
begin
EMIT_LINE("start diagnostic");
EMIT_LINE( "region/file " & PAD_SOURCE_LOGICAL & "/line=" & SOURCE_LINE_NUMBER(1..SOURCE_LINE_NUMBER_LENGTH) & "/column_range=(1,65535)/primary" ); EMIT_LINE( "region/nested/column_range=(" & COLUMN_NUMBER(1..COLUMN_NUMBER_LENGTH) & ")" ); for I in 1..NUMBER_OF_ERROR_MESSAGES loop EMIT( "message/text=quoted "); EMIT_QUOTED_STRING( ERROR_MESSAGE(I)(1..ERROR_MESSAGE_LENGTH(I))); EMIT_NEW_LINE; end loop; EMIT_LINE("end diagnostic"); NUMBER_OF_EMITTED_DIAGNOSTICS := NUMBER_OF_EMITTED_DIAGNOSTICS + 1;
end EMIT_DIAGNOSTIC;
procedure EMIT_ERROR_LIMIT_DIAGNOSTIC is
ERROR_LIMIT_MESSAGE : constant STRING := " Error limit (" & INTEGER'IMAGE(MAX_DIAGNOSTICS) & " ) reached."; begin NUMBER_OF_ERROR_MESSAGES := 1; ERROR_MESSAGE(1)(1..ERROR_LIMIT_MESSAGE'LENGTH) := ERROR_LIMIT_MESSAGE; ERROR_MESSAGE_LENGTH(1) := ERROR_LIMIT_MESSAGE'LENGTH; EMIT_DIAGNOSTIC;
end EMIT_ERROR_LIMIT_DIAGNOSTIC;
procedure EMIT_HEADER is
begin
EMIT_LINE("! Generated by Maarten's fabulous .DIA file generator"); EMIT_LINE("start module");
end EMIT_HEADER;
procedure EMIT_TRAILER is
begin
EMIT_LINE("end module");
end EMIT_TRAILER;
procedure CLEAR_DIAGNOSTIC is
begin
NUMBER_OF_ERROR_MESSAGES := 0;
end CLEAR_DIAGNOSTIC;
function BEGIN_OF_ERROR_MESSAGE return BOOLEAN is begin
return LENGTH > 8 and LINE(1..4) = "PCC-"; end BEGIN_OF_ERROR_MESSAGE;
function END_OF_ERROR_MESSAGE return BOOLEAN is begin
if LINE(LENGTH) /= '!' then return FALSE; else for I in 1..LENGTH-1 loop if LINE(I) /= ASCII.HT and LINE(I) /= ' ' and LINE(I) /= '.' then return FALSE; end if; end loop; return TRUE; end if;
end END_OF_ERROR_MESSAGE;
procedure GET_LINE is
POSITION1, POSITION2 : NATURAL;
begin
POSITION1 := FIND(1, "line "); POSITION1 := POSITION1 + 5; POSITION2 := FIND_NON_NUMERIC(POSITION1); POSITION2 := POSITION2 - 1; SOURCE_LINE_NUMBER_LENGTH := POSITION2 - POSITION1 + 1; SOURCE_LINE_NUMBER(1..SOURCE_LINE_NUMBER_LENGTH) := LINE(POSITION1..POSITION2); exception when NOT_FOUND => SOURCE_LINE_NUMBER(1..2) := "-1"; SOURCE_LINE_NUMBER_LENGTH := 2;
end GET_LINE;
procedure GET_COLUMN is
POSITION1, POSITION2 : NATURAL;
begin
POSITION1 := FIND(1, "column "); POSITION1 := POSITION1 + 7; POSITION2 := FIND_NON_NUMERIC(POSITION1); POSITION2 := POSITION2 - 1; COLUMN_NUMBER_LENGTH := POSITION2 - POSITION1 + 1; COLUMN_NUMBER(1..COLUMN_NUMBER_LENGTH) := LINE(POSITION1..POSITION2); exception when NOT_FOUND => COLUMN_NUMBER(1..1) := "1"; COLUMN_NUMBER_LENGTH := 1;
end GET_COLUMN;
procedure ADD_ERROR_MESSAGE_LINE_TO_DIAGNOSTIC is begin
NUMBER_OF_ERROR_MESSAGES := NUMBER_OF_ERROR_MESSAGES + 1; ERROR_MESSAGE(NUMBER_OF_ERROR_MESSAGES)(1..LENGTH) := LINE(1..LENGTH); ERROR_MESSAGE_LENGTH(NUMBER_OF_ERROR_MESSAGES) := LENGTH;end ADD_ERROR_MESSAGE_LINE_TO_DIAGNOSTIC;
function LINE_IS_EMPTY return BOOLEAN is begin
for I in 1..LENGTH loop if LINE(I) /= ' ' and LINE(I) /= ASCII.HT then return FALSE; end if; end loop; return TRUE;
end LINE_IS_EMPTY;
procedure PROCESS_LINE(LINE : in STRING) is begin
if LINE_IS_EMPTY then return; end if; if BEGIN_OF_ERROR_MESSAGE then READING_ERROR_MESSAGE := TRUE; GET_LINE; GET_COLUMN; ADD_ERROR_MESSAGE_LINE_TO_DIAGNOSTIC; elsif END_OF_ERROR_MESSAGE then EMIT_DIAGNOSTIC; CLEAR_DIAGNOSTIC; READING_ERROR_MESSAGE := FALSE; elsif READING_ERROR_MESSAGE then ADD_ERROR_MESSAGE_LINE_TO_DIAGNOSTIC; end if;
end PROCESS_LINE;
begin -- PAD_DIA
OPEN( FILE => LIS_FILE,
MODE => IN_FILE, NAME => IN_FILE_LOGICAL); CREATE( FILE => DIA_FILE, NAME => OUT_FILE_LOGICAL);
EMIT_HEADER; CLEAR_DIAGNOSTIC; while not END_OF_FILE(LIS_FILE) and not ERROR_LIMIT_REACHED loop
GET_LINE(LIS_FILE, LINE, LENGTH); PROCESS_LINE(LINE(1..LENGTH));
end loop;
if ERROR_LIMIT_REACHED then
EMIT_ERROR_LIMIT_DIAGNOSTIC;
end if;
EMIT_TRAILER;
CLOSE(LIS_FILE);
CLOSE(DIA_FILE);
end PAD_DIA;
------------------------------------cut----------------------
Make sure these LSE definitions are executed. Put them in a .LSE file for example. I keep forgetting the names of the logicals tou auto-load these files. Please look them up, since I don't have the manual here.
------------------------------------cut----------------------DELETE LANGUAGE ADA
DEFINE LANGUAGE ADA -
/COMMENT=( -
ASSOCIATED_IDENTIFIER = PREVIOUS, - NOBEGIN, - NOEND, - NOFIXED, - NOLINE, - TRAILING=("-- |","--")) - /CAPABILITIES=DIAGNOSTICS - /COMPILE_COMMAND="ADA" - /EXPAND_CASE=AS_IS - /FILE_TYPES=(.ADA,.ADC,.ORA_DCL) -
/NOHELP_LIBRARY -
/IDENTIFIER_CHARACTERS= -
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_0123456789" -
/INITIAL_STRING="{compilation_unit}" - /LEFT_MARGIN=CONTEXT_DEPENDENT - /OVERVIEW_OPTIONS=( - MINIMUM_LINES=1, - TAB_RANGE=(4,8)) - /PLACEHOLDER_DELIMITERS=( - REQUIRED= ("{","}"), - REQUIRED_LIST= ("{","}..."), - OPTIONAL= ("[","]"), - OPTIONAL_LIST= ("[","]..."), - PSEUDOCODE= ("½","+")) - /PUNCTUATION_CHARACTERS=",;().'" - /QUOTED_ITEM=(QUOTES="""'") - /RIGHT_MARGIN=80 - /TAB_INCREMENT=4 - /TAG_TERMINATORS=(":") - /TOPIC_STRING="ADA Language_Topics" -/VERSION="V2.0" -
/NOWRAP DEFINE LANGUAGE PROADA -
/COMMENT=( -
ASSOCIATED_IDENTIFIER = PREVIOUS, - NOBEGIN, - NOEND, - NOFIXED, - NOLINE, - TRAILING=("-- |","--")) - /CAPABILITIES=NODIAGNOSTICS - /COMPILE_COMMAND="LSE_PROADA" - /EXPAND_CASE=AS_IS - /FILE_TYPES=(.PAD) -
/NOHELP_LIBRARY -
/IDENTIFIER_CHARACTERS= -
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_0123456789" -
/INITIAL_STRING="{compilation_unit}" - /LEFT_MARGIN=CONTEXT_DEPENDENT - /OVERVIEW_OPTIONS=( - MINIMUM_LINES=1, - TAB_RANGE=(4,8)) - /PLACEHOLDER_DELIMITERS=( - REQUIRED= ("{","}"), - REQUIRED_LIST= ("{","}..."), - OPTIONAL= ("[","]"), - OPTIONAL_LIST= ("[","]..."), - PSEUDOCODE= ("½","+")) - /PUNCTUATION_CHARACTERS=",;().'" - /QUOTED_ITEM=(QUOTES="""'") - /RIGHT_MARGIN=80 - /TAB_INCREMENT=4 - /TAG_TERMINATORS=(":") - /TOPIC_STRING="ADA Language_Topics" -/VERSION="V1.0" -
/NOWRAP DEFINE COMMAND PRO "DO ""COMPILE/REVIEW"", ""END REVIEW"", ""CALL PROTPU"", ""REVIEW /file=dia_file"""
DEFINE COMMAND PROREV "REVIEW /file=dia_file"
DEFINE KEY "F14" "SHOW BUF"
------------------------------cut--------------------------Also copy every Ada ADJUSTMENT, PLACEHOLDER, TAG and TOKEN to a PROADA one. Put these copies also in the .LSE file. They are not necessary, but they make every LSE gadget for Ada also available for Proada (.PAD) files.
Make sure the following TPU procedure is known. E.g., put it in a .TPU file and set a logical to auto-load it.
------------------------------cut--------------------------PROCEDURE protpu
LOCAL filetype, curfile, padfile, lisfile, commando, dclbuf,
adabuf, lisbuf, dclfile;
filetype := FILE_PARSE(GET_INFO(CURRENT_BUFFER,"file_name"),"","",TYPE);
IF filetype <> ".PAD"
THEN
MESSAGE("Buffer does not contain a PROADA file"); ABORT; ENDIF; curfile := FILE_PARSE(GET_INFO(CURRENT_BUFFER,"file_name"),"","", DIRECTORY, NAME); adafile := FILE_PARSE(curfile,".ADA", "", DIRECTORY, NAME, TYPE); oradclfile := FILE_PARSE(curfile,".ORA_DCL","", DIRECTORY, NAME, TYPE); lisfile := FILE_PARSE(curfile,".LIS", "", DIRECTORY, NAME, TYPE); padbufn := padfile; adabufn := FILE_PARSE(curfile,".ADA", "", NAME, TYPE); lisbufn := FILE_PARSE(curfile,".LIS", "", NAME, TYPE);oradclbufn := FILE_PARSE(curfile,".ORA_DCL","", NAME, TYPE); adabuf := GET_INFO(BUFFER, "find_buffer", adabufn); IF adabuf <> 0
THEN
DELETE(adabuf);
ENDIF;
adabuf := CREATE_BUFFER(adabufn, adafile); set (modifiable, adabuf, off);
oradclbuf := GET_INFO(BUFFER, "find_buffer", oradclbufn); IF oradclbuf <> 0
THEN
DELETE(oradclbuf);
ENDIF;
oradclbuf := CREATE_BUFFER(oradclbufn, oradclfile); set (modifiable, oradclbuf, off);
ENDPROCEDURE;
------------------------------cut--------------------------
Good Luck!
Let me know if you are using it. Suggestions are welcomed.
-- Gijs Bok (gijs_at_mbase97.hacktic.nl) Listen to M-BASE music!Received on Fri Aug 27 1993 - 23:49:12 CEST