Google
 

Trailing-Edge - PDP-10 Archives - DEC_CMS-20_V1.0_SRC - cms/sources/reclog.bli
There are no other files named reclog.bli in the archive.
%TITLE 'reclog - recognize log and nolog qualifiers'
MODULE reclog (IDENT = '001',
	       %if
		    %bliss(bliss32)
		%then
		    language(bliss32),
		    addressing_mode(external = long_relative,
			    nonexternal = long_relative)
		%else
		     language(bliss36)
		%fi
		) =
BEGIN

!
!			  COPYRIGHT (C) 1982 BY
!	      DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
!
! THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND  COPIED
! ONLY  IN  ACCORDANCE  WITH  THE  TERMS  OF  SUCH  LICENSE AND WITH THE
! INCLUSION OF THE ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE OR  ANY  OTHER
! COPIES  THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
! OTHER PERSON.  NO TITLE TO AND OWNERSHIP OF  THE  SOFTWARE  IS  HEREBY
! TRANSFERRED.
!
! THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE  WITHOUT  NOTICE
! AND  SHOULD  NOT  BE  CONSTRUED  AS  A COMMITMENT BY DIGITAL EQUIPMENT
! CORPORATION.
!
! DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR  RELIABILITY  OF  ITS
! SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
!

!++
! FACILITY:
!   CMS Library Processor
!
! ABSTRACT:
!   This module contains routines to implement the /LOG and /NOLOG qualifiers
!
! ENVIRONMENT:
!   VAX/VMS, DS-20
!
! AUTHOR: Sue Millar, CREATION DATE: June, 1981
!
! MODIFIED BY:
!
!--
!
! TABLE OF CONTENTS:
!

FORWARD ROUTINE
	labrev,			! See if this is a legal abbreviation
	reclog;			! Recognize and process the log and nolog qualifiers

!
! INCLUDE FILES:
!
%if %bliss(bliss32) %then
    library 'sys$library:starlet';
%else
    require 'jsys:';
%fi
    library 'XPORT:';
    require 'BLISSX:';
    require 'SCONFG:';
    require 'COMUSR:';
    require 'LANGME:';

!
! MACROS:
!
!
! EQUATED SYMBOLS:
bind
    log_spelling = lit('/LOG') : desc_block,
    nolog_spelling = lit('/NOLOG') : desc_block ;
!
!
! OWN STORAGE:
!
    global
	f_log_set : initial (true) ;		! TRUE if /LOG (default)
						! FALSE if /NOLOG
!
 
! EXTERNAL REFERENCES:
    external routine
	bug,					! Report a bug
	codspl,					! Get the spelling of a qualifier
	ers,					! Report a user error
	nxtlex;					! Get the next lexeme

    external
	gratab : gratab_vector ;

    external literal
	s_invqual,				!lexeme is incorrect or misplaced
	s_lexambig;				!lexeme is ambiguous
!
%SBTTL 'reclog - recognize and process /log and /nolog'
GLOBAL ROUTINE reclog ( a_user_string, a_found_log,
			 first_com_qual_x, last_com_qual_x,
			 first_par_qual_x, last_par_qual_x) =

!++
! FUNCTIONAL DESCRIPTION:
!
!	This routine recognizes the /LOG qualifier (or its negative /NOLOG )
!	and sets the global flag f_log_set accordingly. 
!
! FORMAL PARAMETERS:
!
!	a_user_string : address of a descriptor of the remaining users command
!			string, with no leading blanks or tabs. If this string
!			begins with /LOG or /NOLOG , the descriptor will be advances
!			over the qualifier by calling NXTLEX. If it does not begin
!			with the /log or /nolog qualifier, the descriptor is not changed.
!	a_found_log :   Address of a fullword that will be set to true if the /log
!			or /nolog qualifiers is found, false otherwise.
! IMPLICIT INPUTS:
!
!	
!
! IMPLICIT OUTPUTS:
!
!	
!
! ROUTINE VALUE and
! COMPLETION CODES:
!
!	FALSE if the user made a mistake , TRUE if there were no mistakes,
!	whether or not a /log or /nolog qualifier was found.
!
! SIDE EFFECTS:
!
!	The parse tree for the command line is NOT updated to include this
!	qualifier. Only the global symbol f_log_set is updated. The user
! 	string is updated only if one of the qualifiers is found.
!
!--

    BEGIN			!RECLOG

    bind
	user_string = .a_user_string : desc_block,
	found_log = .a_found_log ;
    own
	possible_match :desc_block;
    local
	lexeme : desc_block,		! Lexeme obtained from NXTLEX
	first_qual_x,
	last_qual_x,	
	p_slash,			! pointer to slash
	qual_code,
	save_len,			! Save the user string
	save_ptr ;

    
!Initialize 
    found_log = false;

! Save the user's input in case the qualifiers aren't found
    save_ptr = .user_string[desc_ptr];
    save_len = .user_string[desc_len] ;

! Advance past the lexemes
! Eat up the slash but remember where it was
    if not nxtlex(user_string, k_normal_lex, k_null, lexeme)
    then
	bug(lit('NXTLEX missed slash for RECLOG'));

    p_slash = .lexeme[desc_ptr];

! Obtain the qualifier name
    if not nxtlex(user_string, k_normal_lex, lit('qualifier'), lexeme)
    then
	return false;
! Let the descriptor denote the slash followed by the name
    lexeme[desc_ptr] = ch$plus(.lexeme[desc_ptr], -1);
    lexeme[desc_len] = .lexeme[desc_len] + 1 ;

! Make sure the slash is right in front of the name
    if ch$diff(.lexeme[desc_ptr], .p_slash) gtr 0
    then
	begin				! Switch the space and the slash
	ch$wchar(%c' ', .p_slash);
	ch$wchar(%c'/', .lexeme[desc_ptr]);
	end ;


! Eliminate if qualifier is longer than /NOLOG (remember the slash!)
! and reset the user's input

    if (.lexeme[desc_len] gtr .nolog_spelling[desc_len] + 1)
    then
	begin	
	user_string[desc_len] = .save_len;
	user_string[desc_ptr] = .save_ptr;
	return true;
	end;
! Initialize the descriptor
    $str_desc_init (descriptor = possible_match,
		    string = (0,k_null)) ;

! Find an unambiguous match
    incr n from 1 to 2 do
	begin
	! Examine both command and parameter qualifiers
	if .n eql 1 then
	    begin		! Command qualifiers
    	    first_qual_x = .first_com_qual_x;
	    last_qual_x = .last_com_qual_x ;
	    end
	else
	    begin		! Parameter qualifiers
    	    first_qual_x = .first_par_qual_x;
	    last_qual_x = .last_par_qual_x ;
	    end;
	
        incr i from .first_qual_x to .last_qual_x do

	begin 				! Examine a qualifier
	if labrev(lexeme,codspl(.gratab[.i]), possible_match )
	then
	    qual_code = .gratab[.i] ;
	end ;				! Examine a qualifier
	
    end ; 				! Examine both command and parameter qualifers

    ! Report invalid qualifier
    if .possible_match[desc_len] eql 0
    then
	begin		! Can't find it
	ers(s_invqual,cat(lexeme,' is incorrect, or perhaps misplaced'));
	return false;
	end;

    ! Report ambiguity
    if not ch$fail(ch$find_ch(.possible_match[desc_len],.possible_match[desc_ptr], %c' '))
    then
	begin
	ers(s_lexambig,cat(lexeme, ' could mean: ',possible_match)) ;
	return false;
	end;


! See if we have the qualifier - if we don't, reset the user string
! and return

    if  (.qual_code neq k_log_qual)
    and
	(.qual_code neq k_nolog_qual)
    then
	begin			! We don't have a qualifer
				! So return original user's input
	user_string[desc_len] = .save_len;
	user_string[desc_ptr] = .save_ptr;
   	return true 
	end;

! Now we know we have either /log or /nolog
! We must advance the pointer and set the flags

    found_log = true ;
     
    if .qual_code eql k_log_qual
    then
	f_log_set = true 		! /LOG was specified
    else
        f_log_set = false ;		! /NOLOG was specified

    ! Everything is fine -- return normally

	true

    END;			! end of routine RECLOG
routine labrev(user_str,com_str,match_str) =

!++
!
! Functional Description:
!	This routine examines a string to see if it is an abbreviation for
!	for a CMS keyword. If there are multiple keywords that match the
!	abbreviation, these keywords are concatenated into a single string
!	using a series of calls on the routine 'labrev'.  The blank is used 
!       as a delimiter between each of the keywords.
!
!	Restrictions:	This routine can handle a series of calls to it
! 			for only one abbreviation at one time.
!  				
! Formal Parameters:
!
!	user_str:	address of descriptor for abbreviated keyword. The only
!			time that the string represented by user_str may change
!			is when the match_str has zero length on input.  This
!			is the means by which this routine detects that a new
!			abbreviation is being provided.
!	com_str:	address of descriptor for formal keyword.  The string
!			represented by com_str must not contain any blanks.
! 	match_str:	address of dynamic descriptor of concatenated matching
! 			keyword(s) except when a new abbreviation is being
! 			provided to the routine or when no prior match has
!                       occurred.  When these exceptions occur, this argument
!                       on the call to this routine should be the address of a
!                       descriptor with zero length.
!
! Implicit Inputs:
!
!	None
!
! Implicit Outputs:
!
!	None
!
! Routine Value:
! Completion Codes:
!
!	if a match occurs: routine value = true
! 	if no match:       routine value = false
!
! Side Effects:
!    None.
!
!--
        begin


	own
	    first_match: initial(false),  ! flag:
					  ! 	true = match on previous call
					  !	       (set on first match)
					  !    false = no match on previous 
					  !   	       call


	    abbrev_str : $str_descriptor(class = dynamic) ;
					  ! Save user's input

	map
	    user_str   : ref desc_block ,
	    com_str    : ref desc_block ,
	    match_str  : ref desc_block;


    ! validate if same abbrev or a new one is being submitted
    if not (.first_match)
    then
	begin   ! start no match yet
	if (.match_str[desc_len] neq 0)
	then
            ! match string must be 0 length if no prior match
	    bug(cat(('Attempt to submit a non-zero length descriptor '),
	        ('of match string without a prior match to the '),
                ('routine LABREV.  Non-zero string is '),
		  .match_str)) ;
	end     ! end no match yet
    else
	begin    ! start first_match set
	! abbrev is allowed to change if 0 length match_str
	if (.match_str[desc_len] eql 0)
	then
	    first_match = false
	else
       	    begin    ! start illegal abbrev change
            !+
            ! 	determine if the abbreviation was the same as submitted on
            !	a previous call
            !-

            if (ch$compare(len_comma_ptr(.user_str),
        	len_comma_ptr(abbrev_str)) neq 0)
 	    then
                bug(cat(('Attempt to replace '),abbrev_str,(' with '),
			.user_str,(' in call to routine LABREV'))) ;
					! exit from routine
	    end ;    ! end illegal abbrev change
	end ;    ! end first match set

    !+
    !   eliminate cases where the abbreviation is longer than keyword
    !-
    if (.user_str[desc_len] gtr .com_str[desc_len])
    then
	return FALSE ;    ! exit from routine

    ! compare strings using length of user_str as com_str length
    if (ch$compare(len_comma_ptr(.user_str),.user_str[desc_len],
                       .com_str[desc_ptr]) neq 0)
    then
        return FALSE ;     ! exit from routine here

    if not (.first_match)
    then
        begin    ! start first match segment

        !+
        !	the first match has occurred:
        !	1. the first match flag is set
        !  	2. the desc for match_str is pointed to the keyword desc
        !	3.  the value of true is returned
        !-

        first_match = TRUE ;
        $str_desc_init(descriptor = abbrev_str,
			class = dynamic,
		           string = (.user_str[desc_len], 
				    .user_str[desc_ptr])) ;
							! save abbrev
        ch$move(.user_str[desc_len], .user_str[desc_ptr], .abbrev_str[str$a_pointer]);

	! set output arguments
        $str_desc_init(descriptor = .match_str,
		        string = (.com_str[desc_len], 
		    	.com_str[desc_ptr])) ;

        end      ! end first match segment

    else


        !+
        !	second and subsequent matches
        !
        !	1. append the concatenated string
        ! 	2. build concatented string in work area in the following
        !          order: match_str,blank,com_str.
        !-
	begin

! The following could be done in one statement using a dynamic string 
! descriptor for match_str and the XPORT functions $STR_APPEND and
! $STR_CONCAT. Unfortunately, there appears to be a bug in XPORT
! when this method is attempted.

	    local
		concat_desc : desc_block,	! To build new string
		st,				! Return status
		work_ptr;			! 
		
	 $str_desc_init (descriptor = concat_desc,
		         string = (sum_of_lens(.com_str,lit(' '),.match_str),
							k_null)) ;

	! Get space for string
	st = $xpo_get_mem(characters = .concat_desc[desc_len],
			  result = concat_desc[desc_ptr]);
	! Write original string
        work_ptr = ch$move(len_comma_ptr(.match_str),.concat_desc[desc_ptr]) ;

        ch$wchar_a(%c' ',work_ptr) ;    ! write blank
        ch$move(len_comma_ptr(.com_str),.work_ptr) ;	! Write new match

        match_str[desc_len] = .concat_desc[desc_len] ;     ! set output
        match_str[desc_ptr] = .concat_desc[desc_ptr] ;     ! arguments

	end ;
   TRUE
   end ;

END				! End of module
ELUDOM