//_Header //******************************************************************* // NOVA Central Controls --- Lawrence Livermore Laboratory //******************************************************************* // //_Module_Name: STRING_OPERATIONS _File: [CCDB]STRINGOPS.PRX // //_Description: // // THIS MODULE CONTAINS MISCELLANEOUS STRING OPERATIONS NOT // SUPPORTED BY THE GREAT ALL-POWERFUL PRAXOIDS // //_Call: // // SEE THE INDIVIDULA ROUTINES // //_Identifier: NCCSTD-VAXVMS-139 // //******************************************************************* //_Author: DAVID MCGUIGAN _Creation_Date: 4-FEB-1981 // //_Revisions: // // 1.000 4-FEB-1981 DM Initial Key-in. // 1.001 23-SEP-1981 DM MOVE GET_PADDED_STRING_LENGTH INTO THIS MODULE FROM // GETSTRLEN.PRX // 1.002 23-SEP-1981 DM ADDED ROUTINES MOVE_STRING, MOVE_PADDED_STRING // 1.003 29-OCT-1981 DM ADDED PAD_STRING //******************************************************************* //_End MODULE STRINGOPS // //************************************************************************** // %IF FOR_LSI %SET ENCODE_EXTERNAL_NAMES = TRUE %ENDIF EXPORT STRING_COMPARE, GET_PADDED_STRING_LENGTH, MOVE_STRING, MOVE_PADDED_STRING, INTEGER_TO_STRING, PAD_STRING // //************************************************************************************ //************************************************************************************* // //... THIS ROUTINE COMPARES 2 STRINGS. IT RETURNS -1 IF THE FIRST STRING IS LESS //... THAN THE SECOND. IT RETURNS 1 IF THE FIRST STRING IS GREATER THAN THE //... SECOND. IT RETURNS 0 IF THE 2 STRINGS ARE EQUAL // // CALL : // // RESULT := STRING_COMPARE ( STRING1, STRING2 ) // // WHERE : // STRING1 IS THE FIRST STRING TO BE COMPARED // STRING2 IS THE SECOND STRING TO BE COMPARED // // RESULT IS SET AS DESCRIBED ABOVE // //*************************************************************************************** // FUNCTION STRING_COMPARE ( STRING1 : IN REF PACKED ARRAY [ 1..?N ] OF CHAR, STRING2 : IN REF PACKED ARRAY [ 1..?M ] OF CHAR ) RETURNS RELATION : INTEGER // DECLARE LIMIT : INTEGER ENDDECLARE // LIMIT := N IF M < LIMIT DO LIMIT := M ENDIF // FOR I := 1 TO LIMIT DO IF STRING1 [ I ] < STRING2 [ I ] DO RELATION := -1 RETURN ORIF STRING1 [ I ] > STRING2 [ I ] DO RELATION := 1 RETURN ENDIF ENDFOR IF N < M DO RELATION := -1 ORIF N > M DO RELATION := 1 OTHERWISE RELATION := 0 ENDIF ENDFUNCTION // //********************************************************************************************** //********************************************************************************************** // // THIS FUNCTION WILL RETURN THE LENGTH OF THE NON-PADDED PART OF A // PRAXIS PADDED STRING // //_Call: // // STRING_LENGTH := GET_PADDED_STRING_LENGTH ( PADDED_STRING ) // // WHERE: // PADDED_STRING IS PACKED ARRAY [ 1..?N ] OF CHAR // STRING_LENGTH IS INTEGER // //********************************************************************** // FUNCTION GET_PADDED_STRING_LENGTH ( STRING : IN REF PACKED ARRAY [ 1..?N ] OF CHAR ) RETURNS STRING_LENGTH : INTEGER // DECLARE L : INTEGER INITIALLY N ENDDECLARE // WHILE L > 1 AND ( STRING[ L ] = $ OR STRING[ L ] = $<0> ) DO L *= -1 ENDWHILE STRING_LENGTH := L // ENDFUNCTION // //****************************************************************************************** //****************************************************************************************** // // THIS ROUTINE MOVES THE FIRST STRING TO THE SECOND STRING STARTING AT POSITION+1 IN THE // SECOND STRING. IF THE ENTIRE FIRST STRING CANNOT FIT INTO THE SECOND STRING, AS MUCH // WILL BE MOVED AND POSITION WILL BE SET TO THE LENGHT OF THE SECOND STRING + 1. IF // ALL THE FIRST STRING CAN BE MOVED, POSITION WILL BE SET TO THE LAST POSITION FILLED. // // CALL: // // MOVE_STRING ( STRING1, STRING2, POSITION ) // //************************************************************************************************* // PROCEDURE MOVE_STRING ( STRING1 : IN REF PACKED ARRAY [ 1..?N ] OF CHAR, STRING2 : INOUT REF PACKED ARRAY [ 1..?M ] OF CHAR, POSITION : INOUT REF INTEGER ) // // CHECK IF WE ARE MOVING INTO A VALID POSITION IN STRING2, RETURN IF NOT // IF POSITION >= M DO RETURN ENDIF // IF ( POSITION + N ) > M DO // // TOO MUCH IN STRING1, MOVE WHAT WE CAN AND SET POSITION // FOR I := POSITION+1 TO M DO STRING2[ I ] := STRING1[ I - POSITION ] ENDFOR POSITION := M + 1 OTHERWISE // // WE CAN MOVE ALL OF STRING1, SO LET'S DO IT // FOR I := 1 TO N DO STRING2[ I + POSITION ] := STRING1[ I ] ENDFOR POSITION := POSITION + N ENDIF // ENDPROCEDURE // //****************************************************************************************** //****************************************************************************************** // // THIS ROUTINE MOVES THE FIRST STRING TO THE SECOND STRING STARTING AT POSITION IN THE // SECOND STRING EXCLUDING THE TRAILING BLANKS IN THE FIRST STRING.. IF THE ENTIRE FIRST // STRING EXCLUDING THE TRAILING BLANKS CANNOT FIT INTO THE SECOND STRING, AS MUCH // WILL BE MOVED AND POSITION WILL BE SET TO THE LENGHT OF THE SECOND STRING + 1. IF // ALL THE FIRST STRING CAN BE MOVED, POSITION WILL BE SET TO THE LAST POSITION FILLED. // // CALL: // // MOVE_PADDED_STRING ( STRING1, STRING2, POSITION ) // //************************************************************************************************* // PROCEDURE MOVE_PADDED_STRING ( STRING1 : IN REF PACKED ARRAY [ 1..?N ] OF CHAR, STRING2 : INOUT REF PACKED ARRAY [ 1..?M ] OF CHAR, POSITION : INOUT REF INTEGER ) DECLARE NON_PADDED_LENGTH : INTEGER ENDDECLARE // NON_PADDED_LENGTH := GET_PADDED_STRING_LENGTH ( STRING1 ) // // CHECK IF WE ARE MOVING INTO A VALID POSITION IN STRING2, RETURN IF NOT // IF POSITION >= M DO RETURN ENDIF // IF ( POSITION + NON_PADDED_LENGTH ) > M DO // // TOO MUCH IN STRING1, MOVE WHAT WE CAN AND SET POSITION // FOR I := POSITION+1 TO M DO STRING2[ I ] := STRING1[ I - POSITION ] ENDFOR POSITION := M + 1 OTHERWISE // // WE CAN MOVE ALL OF STRING1, SO LET'S DO IT // FOR I := 1 TO NON_PADDED_LENGTH DO STRING2[ I + POSITION ] := STRING1[ I ] ENDFOR POSITION := POSITION + NON_PADDED_LENGTH ENDIF // ENDPROCEDURE // //******************************************************************************************** //********************************************************************************************* // // THIS ROUTINE WILL CONVERT AN INTEGER TO ITS DECIMAL CHARACTER REPRESENTATION // // CALL: // // INTEGER_TO_STRING ( NUMBER, STRING ) // // WHERE: // NUMBER IS THE INTEGER TO BE CONVERTED // STRING IS THE RESULT BUFFER, STRING WILL BE PADDED WITH BLANKS IF // NUMBER DOES NOT FILL IT. STRING WILL BE FILLED WITH * IF // NUMBER WILL NOT FIT IN IT. // //******************************************************************************************* // PROCEDURE INTEGER_TO_STRING ( NUMBER : IN VAL INTEGER, BUFFER : INOUT REF PACKED ARRAY [ 1..?N ] OF CHAR ) // DECLARE TEMP : INTEGER INDEX : INTEGER INITIALLY 1 TEMP_CHAR : CHAR ENDDECLARE // IF NUMBER = 0 DO BUFFER[ INDEX ] := $0 FOR I := INDEX+1 TO N DO BUFFER[ I ] := $ ENDFOR RETURN ENDIF TEMP := NUMBER IF TEMP < 0 DO TEMP := -TEMP ENDIF WHILE TEMP <> 0 DO IF INDEX <= N DO BUFFER[ INDEX ] := CHAR ( INTEGER ( $0 ) + ( TEMP MOD 10 ) ) INDEX *= +1 TEMP *= / 10 OTHERWISE FOR I := 1 TO N DO BUFFER[ I ] := $* ENDFOR RETURN ENDIF ENDWHILE // // STRING WAS BUILT BACKWARDS, REVERSE IT // NOTE, INDEX IS POST INCREMENTED SO IT IS 1 MORE THEN THE END OF THE STRING // FOR I := 1 TO (INDEX-1)/2 DO TEMP_CHAR := BUFFER[ I ] BUFFER[ I ] := BUFFER[ INDEX-I ] BUFFER[ INDEX-I ] := TEMP_CHAR ENDFOR IF NUMBER < 0 DO // // NUMBER WAS NEGATIVE, PUT THE SIGN IN // FOR I := INDEX-1 DOWNTO 1 DO BUFFER[ I+1 ] := BUFFER[ I ] ENDFOR BUFFER[ 1 ] := $- INDEX *= +1 ENDIF // // NOW PAD WITH BLANKS // FOR I := INDEX TO N DO BUFFER[ I ] := $ ENDFOR // ENDPROCEDURE // //******************************************************************************************* //****************************************************************************************** // THIS PROCEDURE WILL MOVE STRING1 TO STRING2 AND PAD STRING2 WITH BLANKS IF NEEDED // PROCEDURE PAD_STRING ( STRING1 : IN REF PACKED ARRAY [ 1..?N ] OF CHAR, STRING2 : OUT REF PACKED ARRAY [ 1..?M ] OF CHAR ) // DECLARE LIMIT : INTEGER ENDDECLARE // LIMIT := N IF M < LIMIT DO LIMIT := M ENDIF // FOR I := 1 TO LIMIT DO STRING2[ I ] := STRING1[ I ] ENDFOR // FOR I := LIMIT+1 TO M DO STRING2[ I ] := $ ENDFOR // ENDPROCEDURE // ENDMODULE