From:	CSBVAX::MRGATE!info-vax-RELAY@KL.SRI.COM@SMTP 28-JUL-1988 12:40
To:	ARISIA::EVERHART
Subj:	Re: Bug in VAXTPU searching? (ANY)


Received: from ucbvax.berkeley.edu by KL.SRI.COM with TCP; Fri, 22 Jul 88 23:36:34 PDT
Received: by ucbvax.berkeley.edu (5.59/1.28)
	id AA03252; Fri, 22 Jul 88 18:21:05 PDT
Received: from USENET by ucbvax.Berkeley.EDU with netnews
	for info-vax@kl.sri.com (info-vax@kl.sri.com)
	(contact usenet@ucbvax.Berkeley.EDU if you have questions)
Date: 21 Jul 88 15:03:50 GMT
From: munnari!vuwcomp!windy!srwhmdr@uunet.uu.net  (Malcolm Robbins)
Organization: DSIR, Wellington, NZ
Subject: Re: Bug in VAXTPU searching? (ANY)
Message-Id: <1712@windy.dsir.govt.nz>
References: <1711@windy.dsir.govt.nz>
Sender: info-vax-request@kl.sri.com
To: info-vax@kl.sri.com

In article <1711@windy.dsir.govt.nz>, srwhmdr@windy.dsir.govt.nz (Malcolm Robbins) writes:

> 
> What I'd like to know is:
> 
>   o  How can I do what I intended, which is to search for an alphabetic
>      character at the start of a line, in a reliable way?
> 
> Any replies would be greatly appreciated. In fact to show my appreciation
> I'll post a "detab" procedure for removing TABs in a file to this newsgroup
> shortly.

OK, here's the detab procedure, but you can have it only if you've considered
the problem I've been having :-).

Simply extract the SHAR file, @ it to extract DETAB.TPU. To merge it with EVE
load it, and enter EXTEND TPU. Now DETAB is an EVE command. Note that it works
no matter what the tab settings are. e.g. It works for 

	Command:  SET TABS EVERY 13
	Command:  SET TABS AT 10 50 55 60

etc.

....................... Cut between dotted lines and save. .....................
$!.............................................................................
$! VAX/VMS archive file created by VMS_SHARE V06.00 26-May-1988.
$!
$! VMS_SHARE was written by James Gray (Gray:OSBUSouth@Xerox.COM) from
$! VMS_SHAR by Michael Bednarek (U3369429@ucsvc.dn.mu.oz.au).
$!
$! To unpack, simply save, concatinate all parts into one file and
$! execute (@) that file.
$!
$! This archive was created by user SRWHMDR
$! on  6-APR-1866 20:07:23.78.
$!
$! It contains the following 1 file:
$!        DETAB.TPU
$!
$!==============================================================================
$ SET SYMBOL/SCOPE=( NOLOCAL, NOGLOBAL )
$ VERSION = F$GETSYI( "VERSION" )
$ IF VERSION .GES "V4.4" THEN GOTO VERSION_OK
$ WRITE SYS$OUTPUT "You are running VMS ''VERSION'; ", -
    "VMS_SHARE V06.00 26-May-1988 requires VMS V4.4 or higher."
$ EXIT 44 
$VERSION_OK:
$ GOTO START
$
$UNPACK_FILE:
$ WRITE SYS$OUTPUT "Creating ''FILE_IS'"
$ DEFINE/USER_MODE SYS$OUTPUT NL:
$ EDIT/TPU/COMMAND=SYS$INPUT/NODISPLAY/OUTPUT='FILE_IS'/NOSECTION -
    VMS_SHARE_DUMMY.DUMMY
b_part := CREATE_BUFFER( "{Part}", GET_INFO( COMMAND_LINE, "file_name" ) )
; s_file_spec := GET_INFO( COMMAND_LINE, "output_file" ); SET( OUTPUT_FILE
, b_part, s_file_spec ); b_errors := CREATE_BUFFER( "{Errors}" ); i_errors 
:= 0; pat_beg_1 := ANCHOR & "-+-+-+ Beginning"; pat_beg_2 := LINE_BEGIN 
& "+-+-+-+ Beginning"; pat_end := ANCHOR & "+-+-+-+-+ End"; POSITION
( BEGINNING_OF( b_part ) ); i_append_line := 0; LOOP EXITIF MARK( NONE 
) = END_OF( b_part ); s_x := ERASE_CHARACTER( 1 ); IF s_x = "+" THEN r_skip 
:= SEARCH( pat_beg_1, FORWARD, EXACT ); IF r_skip <> 0 THEN s_x := ""
; MOVE_HORIZONTAL( -CURRENT_OFFSET ); ERASE_LINE; ENDIF; ENDIF
; IF s_x = "-" THEN r_skip := SEARCH( pat_end, FORWARD, EXACT ); IF r_skip <
> 0 THEN s_x := ""; MOVE_HORIZONTAL( -CURRENT_OFFSET ); m_skip := MARK( NONE )
; r_skip := SEARCH( pat_beg_2, FORWARD, EXACT ); IF r_skip <> 0 THEN POSITION
( END_OF( r_skip ) ); MOVE_HORIZONTAL( -CURRENT_OFFSET ); MOVE_VERTICAL( 1 )
; MOVE_HORIZONTAL( -1 ); ELSE POSITION( END_OF( b_part ) ); ENDIF; ERASE
( CREATE_RANGE( m_skip, MARK( NONE ), NONE ) ); ENDIF; ENDIF
; IF s_x = "V" THEN s_x := ""; IF i_append_line <> 0 THEN APPEND_LINE
; MOVE_HORIZONTAL( -CURRENT_OFFSET ); ENDIF; i_append_line := 1; MOVE_VERTICAL
( 1 ); ENDIF; IF s_x = "X" THEN s_x := ""; IF i_append_line <
> 0 THEN APPEND_LINE; MOVE_HORIZONTAL( -CURRENT_OFFSET ); ENDIF
; i_append_line := 0; MOVE_VERTICAL( 1 ); ENDIF; IF s_x <> "" THEN i_errors 
:= i_errors + 1; s_text := CURRENT_LINE; POSITION( b_errors ); COPY_TEXT
( "The following line could not be unpacked properly:" ); SPLIT_LINE
; COPY_TEXT( s_x ); COPY_TEXT( s_text ); POSITION( b_part ); MOVE_VERTICAL( 1 
); ENDIF; ENDLOOP; POSITION( BEGINNING_OF( b_part ) ); LOOP r_x := SEARCH( "`"
, FORWARD, EXACT ); EXITIF r_x = 0; POSITION( r_x ); ERASE_CHARACTER( 1 )
; IF CURRENT_CHARACTER = "`" THEN MOVE_HORIZONTAL( 1 ); ELSE COPY_TEXT( ASCII
( INT( ERASE_CHARACTER( 3 ) ) ) ); ENDIF; ENDLOOP; IF i_errors = 0 THEN SET
( NO_WRITE, b_errors, ON ); ELSE POSITION( BEGINNING_OF( b_errors ) )
; COPY_TEXT( FAO( "The following !UL errors were detected while unpacking !AS"
, i_errors, s_file_spec ) ); SPLIT_LINE; SET( OUTPUT_FILE, b_errors
, "SYS$COMMAND" ); ENDIF; EXIT; 
$ DELETE VMS_SHARE_DUMMY.DUMMY;*
$ CHECKSUM 'FILE_IS
$ WRITE SYS$OUTPUT " CHECKSUM ", -
  F$ELEMENT( CHECKSUM_IS .EQ. CHECKSUM$CHECKSUM, ",", "failed!,passed." )
$ RETURN
$
$START:
$ FILE_IS = "DETAB.TPU"
$ CHECKSUM_IS = 1750754036
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
X!
X! This procedure removes tabs and writes a message
X!
Xprocedure eve_detab
X
XLOCAL   num_tabs;
X
XMESSAGE ("Detabbing buffer...");
Xnum_tabs := xeve$detab;
XIF num_tabs = 0 THEN
X    MESSAGE ('No TABs in buffer')
XELSE
X    MESSAGE (FAO ('Converted !UL tab!%S', num_tabs))
XENDIF;
XENDPROCEDURE
X
X!
X! Boolean function which returns TRUE if there are tabs in the buffer.
X! This is extracted from the detab routine since it is called by the
X! rectangular block cut/paste procedures and the sort procedure.
X!
XPROCEDURE xeve$tabs_present
X
XLOCAL   my_tab;                 ! Range containing the tab character if found
X
X! disable messages
X!
XON_ERROR
XENDON_ERROR;
X
Xmy_tab := SEARCH (ASCII(9), FORWARD);
XIF my_tab = 0 THEN
X    my_tab := SEARCH (ASCII(9), REVERSE);
XENDIF;
X
XIF my_tab = 0 THEN
X    RETURN 0;
XELSE
X    RETURN 1;
XENDIF;
XENDPROCEDURE
X
X!
X! This procedure replaces TABs with spaces and returns a count of the
X! number of TABs replaced
X!
XPROCEDURE xeve$detab
X
XLOCAL   dest_column,            ! Column to insert spaces to
X        this_position,          ! Save current position
X        count,                  ! A count of the number of tabs converted
X        timer_string,
X        my_tab;                 ! Range containing the tab character if found
X
XON_ERROR
XENDON_ERROR;
X
XIF NOT xeve$tabs_present THEN
X    RETURN 0;
XENDIF;
X
Xtimer_string := GET_INFO (SYSTEM, 'timed_message');
XSET (TIMER, ON, "Detabing...");
Xthis_position := MARK (NONE);
XPOSITION (BEGINNING_OF (CURRENT_BUFFER));
Xcount := 0;
Xtabs := GET_INFO (CURRENT_BUFFER, "tab_stops");
X
XLOOP
X    my_tab := SEARCH (ASCII (9), FORWARD);
X    EXITIF my_tab = 0;
X    count := count + 1;
X    POSITION (my_tab);
X    ERASE (my_tab);
X!
X!   If the tabs stops are set every n characters then tabs is an integer
X!   and expanding is easy. If tabs are set at differing positions the problem
X!   is a little more complicated
X!
X    IF GET_INFO (tabs, "type") = INTEGER THEN
X        dest_column := (CURRENT_OFFSET / tabs + 1) * tabs + 1;
X    ELSE
X        dest_column := xeve$get_offset (tabs, CURRENT_OFFSET);
X    ENDIF;
X    eve$to_column (dest_column)
XENDLOOP;
X
XPOSITION (this_position);
XSET (TIMER, ON, timer_string);
XRETURN count;
XENDPROCEDURE
X
X!
X! This function returns the column position of the next tab stop from
X! the current position. i.e. "tabs" contains the tabs stop string and
X! offset contains the current position.
X! This function is used within xeve$detab so it can replace tabs with
X! the right number of spaces.
X!
XPROCEDURE xeve$get_offset (tabs, offset)
X
XLOCAL   end_pos,
X        tab_string,
X        local_tabs,
X        num;
X
Xlocal_tabs := tabs;
XLOOP
X    end_pos := INDEX (local_tabs, ' ');
X    IF end_pos = 0 THEN
X        end_pos := LENGTH (local_tabs) + 1
X    ENDIF;
X    tab_string := SUBSTR (local_tabs, 1, end_pos - 1);
X    num := INT (tab_string);
X    EXITIF num > offset;
X    local_tabs := SUBSTR (local_tabs, end_pos + 1, LENGTH (local_tabs));
X    IF local_tabs = '' THEN
X        RETURN offset + 2
X    ENDIF;
XENDLOOP;
X
XRETURN num;
XENDPROCEDURE
X
X
XDEFINE_KEY ("eve_detab", KEY_NAME ("D", SHIFT_KEY));
$ GOSUB UNPACK_FILE
$ EXIT

+-----------------------------------------------------------------------------+
| Malcolm Robbins,                                                            |
| Department of Scientific and Industrial Research                            |
| New Zealand.                                                                |
|                                                                             |
| Internet: srwhmdr@wnv.dsir.govt.nz			      		      |
| Pacnet:   PSI%(05301)4600000060::SRWHMDR				      |
+-----------------------------------------------------------------------------+
