[comp.os.vms] TPU's SPANL: Feature or Bug?

W_COSTA@UNHH.BITNET (11/15/87)

Hello Netlandia,

    I am posting the following for my friend from across the puddle, Carlo
    Mekenkamp.  He writes:

       I do not understand the behaviour of SPANL. pattern:= SPANL
       (string) When I read documentation it says that: it
       `Returns a pattern that matches the longest string of
       characters that contains only characters appearing in the
       string used as a parameter. ... SPANL considers the
       end-of-line condition as a match and continues the pattern
       beyond the end-of-line... ' SPANL match match as least one
       character or it fails. This DEMO.TPU program demonstrates a
       weird behaviour of SPANL which is not in accordance with
       the manual. Could anyone tell me if it is a bug or a
       feature? /Carlo Mekenkamp <MEKENKAMP@HLERUL5.BITNET>

 ...................... Cut between dotted lines and save ......................
$!..............................................................................
$! VAX/VMS archive file created by VMS_SHAR V-5.01 01-Oct-1987
$! which was written by Michael Bednarek (U3369429@ucsvc.dn.mu.oz.au)
$! To unpack, simply save and execute (@) this file.
$!
$! This archive was created by W_COSTA
$! on Saturday 14-NOV-1987 16:25:06.03
$!
$! It contains the following 1 file:
$! DEMO.TPU
$!==============================================================================
$ Set Symbol/Scope=(NoLocal,NoGlobal)
$ Version=F$GetSYI("VERSION") ! See what VMS version we have here:
$ If Version.ges."V4.4" then goto Version_OK
$ Write SYS$Output "Sorry, you are running VMS ",Version, -
                ", but this procedure requires V4.4 or higher."
$ Exit 44
$Version_OK: CR[0,8]=13
$ Pass_or_Failed="failed!,passed."
$ Goto Start
$Convert_File:
$ Read/Time_Out=0/Error=No_Error1/Prompt="creating ''File_is'" SYS$Command ddd
$No_Error1: Define/User_Mode SYS$Output NL:
$ Edit/TPU/NoSection/NoDisplay/Command=SYS$Input/Output='File_is' -
        VMS_SHAR_DUMMY.DUMMY
f:=Get_Info(Command_Line,"File_Name");b:=Create_Buffer("",f);
o:=Get_Info(Command_Line,"Output_File");Set(Output_File,b,o);
Position(Beginning_of(b));Loop x:=Erase_Character(1);Loop ExitIf x<>"V";
Move_Vertical(1);x:=Erase_Character(1);Append_Line;
Move_Horizontal(-Current_Offset);EndLoop;Move_Vertical(1);
ExitIf Mark(None)=End_of(b) EndLoop;Position(Beginning_of(b));Loop
x:=Search("`",Forward,Exact);ExitIf x=0;Position(x);Erase_Character(1);
If Current_Character='`' then Move_Horizontal(1);else
Copy_Text(ASCII(INT(Erase_Character(3))));EndIf;EndLoop;Exit;
$ Delete VMS_SHAR_DUMMY.DUMMY;*
$ Checksum 'File_is
$ Success=F$Element(Check_Sum_is.eq.CHECKSUM$CHECKSUM,",",Pass_or_Failed)+CR
$ Read/Time_Out=0/Error=No_Error2/Prompt=" CHECKSUM ''Success'" SYS$Command ddd
$No_Error2: Return
$Start:
$ File_is="DEMO.TPU"
$ Check_Sum_is=509356731
$ Copy SYS$Input VMS_SHAR_DUMMY.DUMMY
X!Hardware:  VAX-11/785
X!System:    VAX/VMS 4.6
X!Program:   LSEDIT V2.0
X!These procedures demonstrate the effect of a SEARCH with a SPANL-pattern
X!It tries to search for spaces: SEARCH(ANCHOR&SPANL(' ', FORWARD));
X!From: VAX Text Processing Utility Reference Manual AA-EC64C-TE
X!Page 4-215:
X!SPANL:
X!  Returns a pattern that matches the longest string of characters that
X!  contains only characters appearing in the string used as parameter.
X!DESCRIPTION:
X!  SPANL is similar to SPAN. However, SPANL considers the end-of-line
X!  condition as a match and continues the pattern beyond the end-of-line. It
X!  continues the search for a pattern until it finds a character that does not
X!  appear in the string used as a parameter or until an end-of-search condition
X!  is found. The end-of-search condition is the beginning of the buffer if the
X!  direction of the search is REVERSE, or the end of the buffer if the
X!  direction of the search is FORWARD.
X!  SPANL much match at least one character or it fails.
X!But it only works in the following case:
X!<cursor><spaces><newline><spaces><nonspace>
X!Not in the cases
X!<cursor><newline><spaces><nonspace>
X!and
X!<cursor><spaces><newline><nonspace>
X!Demonstration is given by CALL DEMO
X!When for a key is asked, ^Z will ABORT Demonstration and place you
X!in the demonstration buffer, the space-key or return-key continues.
X!Stripped procedure: demo_search is the procedure which calls SEARCH
X!
XPROCEDURE demo_search (demo_n)
XLOCAL
X    x_string, x_range;
X    x_string:= ASCII (32);
X    x_range:= SEARCH (ANCHOR&SPANL (x_string), FORWARD);
X    IF x_range= 0 THEN
X        MESSAGE (FAO ('Demo !UL: No match found for spaces', demo_n))
X    ELSE
X        MESSAGE (FAO ('Demo !UL: Length of range: !UL', demo_n,
X                       LENGTH (x_range)));
X        my_range:= CREATE_RANGE (BEGINNING_OF (x_range),
X                                  END_OF (x_range), BOLD);
X    ENDIF;
XENDPROCEDURE
X
XPROCEDURE demo_init
X    IF GET_INFO (my_buffer, 'TYPE')= UNSPECIFIED THEN
X        my_last_buffer:= CURRENT_BUFFER;
X        dummy_window:= CREATE_WINDOW (1, 2, ON);
X        dummy_buffer:= CREATE_BUFFER ('dummy_buffer');
X        my_window:= CREATE_WINDOW (3, 10, ON);
X        my_buffer:= CREATE_BUFFER ('my_buffer');
X        SET (STATUS_LINE, dummy_window, NONE, 'Is there a bug??');
X        SET (STATUS_LINE, my_window, REVERSE, 'Demonstration window');
X        SET (NO_WRITE, my_buffer, ON);
X        MAP (dummy_window, dummy_buffer);
X        POSITION (dummy_buffer);
X        COPY_TEXT ('Demonstration of SPANL');
X        POSITION (BEGINNING_OF (dummy_buffer));
X        UPDATE (dummy_window);
X        MAP (my_window, my_buffer);
X    ENDIF
XENDPROCEDURE
X
XPROCEDURE demo_wait
XLOCAL
X    x_key;
X    my_mark:= MARK (UNDERLINE);
X    POSITION (END_OF (my_buffer));
X    MOVE_HORIZONTAL (-1);
X    my_range2:= CREATE_RANGE (BEGINNING_OF (my_buffer),
X                               MARK (NONE), REVERSE);
X    MOVE_HORIZONTAL (1);
X    COPY_TEXT ('Enter any key to continue');
X    POSITION (my_mark);
X    UPDATE (my_window);
X    x_key:= READ_KEY;
X    IF x_key= CTRL_Z_KEY THEN
X        abort
X    ENDIF
XENDPROCEDURE
X
XPROCEDURE demo_exit
X    UNMAP (my_window);
X    UNMAP (dummy_window);
X    DELETE (dummy_window);
X    DELETE (dummy_buffer);
X    DELETE (my_buffer);
X    DELETE (my_window);
X    POSITION (my_last_buffer);
XENDPROCEDURE
X
XPROCEDURE demo
X    demo_init;
X    demo_1;
X    demo_wait;
X    demo_2;
X    demo_wait;
X    demo_3;
X    demo_wait;
X    demo_exit;
XENDPROCEDURE
X
XPROCEDURE demo_1
X    my_range:= 0;
X    ERASE (my_buffer);
X    POSITION (BEGINNING_OF (my_buffer));
X    COPY_TEXT ('       ');
X    SPLIT_LINE;
X    COPY_TEXT ('       Demo1 test SPANL with spaces on line');
X    SPLIT_LINE;
X    COPY_TEXT ('followed by spaces on next line');
X    SPLIT_LINE;
X    COPY_TEXT ('This is normal behaviour as documented');
X    POSITION (BEGINNING_OF (my_buffer));
X    demo_search (1);
XENDPROCEDURE
X
XPROCEDURE demo_2
XLOCAL
X    x_range;
X    my_range:= 0;
X    ERASE (my_buffer);
X    POSITION (BEGINNING_OF (my_buffer));
X    SPLIT_LINE;
X    COPY_TEXT ('       Demo2 test SPANL with empty line');
X    SPLIT_LINE;
X    COPY_TEXT ('followed by spaces on next line');
X    SPLIT_LINE;
X    COPY_TEXT ('This finds a zero-length range');
X    SPLIT_LINE;
X    COPY_TEXT ('Not according to documentation');
X    POSITION (BEGINNING_OF (my_buffer));
X    demo_search(2);
XENDPROCEDURE
X
XPROCEDURE demo_3
XLOCAL
X    x_range;
X    my_range:= 0;
X    ERASE (my_buffer);
X    POSITION (BEGINNING_OF (my_buffer));
X    COPY_TEXT ('       ');
X    SPLIT_LINE;
X    COPY_TEXT ('Demo3  test SPANL with spaces on line');
X    SPLIT_LINE;
X    COPY_TEXT ('followed by NO spaces on next line');
X    SPLIT_LINE;
X    COPY_TEXT ('This one even fails finding a range');
X    SPLIT_LINE;
X    COPY_TEXT ('Not according to documentation');
X    POSITION (BEGINNING_OF (my_buffer));
X    demo_search(3);
XENDPROCEDURE
$ GoSub Convert_File
$ Exit