DEFINITION MODULE MiscFuncs;

        (********************************************************)
        (*                                                      *)
        (*              Miscellaneous procedures for            *)
        (*               a variety of applications              *)
        (*                                                      *)
        (*  Programmer:         P. Moylan                       *)
        (*  Started:            21 May 2017                     *)
        (*  Last edited:        19 May 2024                     *)
        (*  Status:             OK                              *)
        (*                                                      *)
        (********************************************************)


FROM SYSTEM IMPORT LOC, CARD16, CARD32;
FROM Arith64 IMPORT CARD64LE;
FROM FileOps IMPORT ChanId;


TYPE
    CharArrayPointer = POINTER TO ARRAY [0..MAX(CARDINAL) DIV 4] OF CHAR;
    LocArrayPointer = POINTER TO ARRAY [0..MAX(CARDINAL) DIV 4] OF LOC;

PROCEDURE EVAL (f: ARRAY OF LOC);

    (* A do-nothing procedure - we use it for evaluating a function and *)
    (* ignoring the result.                                             *)

PROCEDURE Swap2 (VAR (*INOUT*) arg: CARD16): CARD16;

    (* Reverses the byte order of a 2-byte argument.  Used to convert   *)
    (* between big-endian and little-endian forms of a CARD16.          *)

PROCEDURE Swap4 (VAR (*INOUT*) arg: CARD32): CARD32;

    (* Reverses the byte order of a 4-byte argument.  Used to convert   *)
    (* between big-endian and little-endian forms of a CARD32.          *)

PROCEDURE StripWhitespace (VAR (*INOUT*) arg: ARRAY OF CHAR);

    (* Removes leading and trailing whitespace from arg.  The whitespace *)
    (* characters are space, tab, carriage return, and line feed.        *)

PROCEDURE StringMatch (str1, str2: ARRAY OF CHAR): BOOLEAN;

    (* Checks if str1 and str2 are equal, modulo character case. *)

PROCEDURE HeadMatch (VAR (*IN*) str: ARRAY OF CHAR;
                                template: ARRAY OF CHAR): BOOLEAN;

    (* String equality, with case differences ignored.  We check that   *)
    (* template is a leading substring of str.                          *)

PROCEDURE ToLower (VAR (*INOUT*) string: ARRAY OF CHAR);

    (* Converts all letters in string to lower case. *)

PROCEDURE AppendString (new: ARRAY OF CHAR;  VAR (*INOUT*) result: ARRAY OF CHAR;
                                          VAR (*INOUT*) pos: CARDINAL);

    (* Puts new into the result array, starting at result[pos].      *)
    (* On return pos is updated to the next unused array index.      *)

PROCEDURE SplitArg (VAR (*OUT*) first: ARRAY OF CHAR;
                    VAR (*INOUT*) arg: ARRAY OF CHAR);

    (* Finds the first space character in arg, and assigns everything   *)
    (* before it to first, and everything after it to arg.  Leading and *)
    (* trailing spaces are stripped.  If there is no internal space,    *)
    (* arg is copied to first and arg then becomes the empty string.    *)

PROCEDURE SetINIorTNIname (appname: ARRAY OF CHAR;  TNI: BOOLEAN;
                                        VAR (*OUT*) INIname: ARRAY OF CHAR);

    (* Sets INIname to appname.INI or appname.TNI, depending on the *)
    (* TNI parameter.                                               *)

PROCEDURE GetNum (VAR (*IN*) str: ARRAY OF CHAR;  VAR (*INOUT*) pos: CARDINAL): CARDINAL;

    (* Picks up a number at str[pos], increments pos. *)

PROCEDURE WriteCard (N: CARDINAL);

    (* Writes N in decimal to standard output. *)

PROCEDURE ConvertCard (number: CARDINAL;  VAR (*OUT*) result: ARRAY OF CHAR;
                                          VAR (*INOUT*) pos: CARDINAL);

    (* Converts number to decimal, left justified starting at result[pos].      *)
    (* On return pos is updated to the next unused array index.                 *)

PROCEDURE AppendCard (number: CARDINAL;  VAR (*OUT*) message: ARRAY OF CHAR);

    (* Converts number to decimal, appends it to the existing message.  *)

PROCEDURE AppendInt (number: INTEGER;  VAR (*OUT*) message: ARRAY OF CHAR);

    (* Converts number to decimal, appends it to the existing message.  *)

PROCEDURE ConvertCard64 (number: CARD64LE;  VAR (*OUT*) result: ARRAY OF CHAR;
                                          VAR (*INOUT*) pos: CARDINAL);

    (* Converts number to decimal, left justified starting at result[pos].      *)
    (* On return pos is updated to the next unused array index.                 *)

PROCEDURE ConvertCardRJ (number: CARDINAL;  VAR (*OUT*) result: ARRAY OF CHAR;
                             fieldwidth: CARDINAL;  VAR (*INOUT*) pos: CARDINAL);

    (* Like ConvertCard, but right justified with space fill.     *)

PROCEDURE ConvertCard64RJ (number: CARD64LE;  VAR (*OUT*) result: ARRAY OF CHAR;
                             fieldwidth: CARDINAL;  VAR (*INOUT*) pos: CARDINAL);

    (* Like ConvertCardRJ, but for CARD64 numbers.     *)

PROCEDURE ConvertCardZ (number: CARDINAL;  VAR (*OUT*) result: ARRAY OF CHAR;
                             fieldwidth: CARDINAL;  VAR (*INOUT*) pos: CARDINAL);

    (* Like ConvertCard, but uses a fixed fieldwidth and leading zero fill.     *)

PROCEDURE ConvertDecimal (VAR (*IN*) numberstring: ARRAY OF CHAR;
                                          VAR (*INOUT*) pos: CARDINAL): CARDINAL;

    (* Converts decimal string to cardinal, starting from numberstring[pos].    *)
    (* On return pos is updated to the next unused array index.                 *)

PROCEDURE ConvertDecimal64 (VAR (*IN*) numberstring: ARRAY OF CHAR;
                                          VAR (*INOUT*) pos: CARDINAL): CARD64LE;

    (* Like ConvertDecimal, but gives a 64-bit result.  *)

PROCEDURE HexEncodeArray (VAR (*IN*) input: ARRAY OF LOC;  N: CARDINAL;
                          VAR (*OUT*) result: ARRAY OF CHAR);

    (* Each byte of input becomes two hexadecimal digits. *)

PROCEDURE DecodeHex (input: ARRAY OF CHAR): CARDINAL;

    (* Converts a hexadecimal number to cardinal. *)

PROCEDURE DecodeHexString (VAR (*IN*) input: ARRAY OF CHAR;
                           VAR (*OUT*) result: ARRAY OF LOC);

    (* Each two characters of input is interpreted as a pair of two hexadecimal digits. *)

PROCEDURE AddEOL (VAR (*INOUT*) buffer: ARRAY OF CHAR): CARDINAL;

    (* Appends a CRLF to the buffer contents, returns the total string length. *)

PROCEDURE LockScreen;

    (* Critical section protection for writing to the screen. *)

PROCEDURE UnlockScreen;

    (* Critical section protection for writing to the screen. *)

PROCEDURE OpenLogFile (name: ARRAY OF CHAR): ChanId;

    (* Opens a log file.  This thread retains exclusive access   *)
    (* until it calls CloseLogFile.                              *)

PROCEDURE CloseLogFile (id: ChanId);

    (* Closes the specified file, and releases the exclusive lock. *)

END MiscFuncs.

