--
--	Inmos Libraries
--	Copyright (C) 1988, 1989, 1990, 1991, 1993  Inmos Limited
--
--	This library is free software; you can redistribute it and/or
--	modify it under the terms of the GNU Lesser General Public
--	License as published by the Free Software Foundation; either
--	version 2 of the License, or (at your option) any later version.
--
--	This library is distributed in the hope that it will be useful,
--	but WITHOUT ANY WARRANTY; without even the implied warranty of
--	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
--	Lesser General Public License for more details.
--
--	You should have received a copy of the GNU Lesser General Public
--	License along with this library; if not, write to the Free Software
--	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
--

--** @module string

#OPTION "E V" -- no compiler libraries, no vector space
#COMMENT "String library V1.4 16/06/93"
#COMMENT "(c) Copyright INMOS Limited 1988"
#USE "convert.lib"
--{{{  history
-- V1.0,  1-Jul-88
-- V1.1, 22-Mar-90 SRH
-- V1.2, 21-Aug-90; a negative value for the field width in append.int and
-- append.hex.int made an explicit error. SRH
-- V1.3, 16-Oct-92; in append.int, parameter 'field' -> 'width', for
-- consistency.  SRH
-- V1.4, 16-Jun-93: nibbles.per.word now commented as to the value it
-- has been given.  SRH
--}}}
--{{{  append.char
--* Write a byte into a string.
--
-- If accessing str[ len ], for len on entry, is invalid then this
-- routine acts as an invalid process.
--
-- @param len on entry: the byte char will be written at str[ len ]; on
--   exit: len will be one greater than it was on entry
-- @param str the string to write char to
-- @param char the byte which is to be written into str
PROC append.char (INT len, []BYTE str, VAL BYTE char)
  SEQ
    str[len] := char
    len := len + 1
:
--}}}
--{{{  append.text
--* Concatenate two strings.
--
-- If str is not long enough to hold the concatenation then this
-- routine acts as an invalid process.
--
-- @param len on entry: the index of str where the first character of
--   text is to go; on exit: the index of str immediately after the
--   last character of text inserted, or SIZE str if the last character
--   of text was placed in the last position of str
-- @param str the concatenation of what str was on entry with text,
--   where text is placed in positions str[ len ] to str[ len + (SIZE
--   text) - 1 ] inclusive, where len here is that on entry
-- @param text the string to be concatenated with str, text being the
--   second string
PROC append.text (INT len, []BYTE str, VAL []BYTE text)
  VAL extra.len IS (SIZE text):
  SEQ
    [str FROM len FOR extra.len] := text
    len := len + extra.len
:
--}}}
--{{{  append.int
--* Convert an integer into its representation as ASCII decimal digits,
-- with leading spaces if desired, and write this into a given string.
--
-- If str overflows then this routine acts as an invalid process. The
-- conversion of number will include a minus sign if applicable.
--
-- @param len on entry: the index of str at which the first character
--   of the ASCII conversion of number is to be written; on exit: the
--   index of str immediately after where the last character of the
--   ASCII conversion of number was written, or SIZE str if this last
--   character was written into the last positon of str
-- @param str the string into which the ASCII conversion of number is
--   to be written
-- @param number the integer to be converted to an ASCII representation
--   and then written into str
-- @param width the field width of the ASCII representation of number:
--   if number cannot be represented in width characters then the
--   representation is widened as necessary; if width is larger than
--   necessary then padding spaces are added on the left; it is an
--   error if width is negative
PROC append.int (INT len, []BYTE str, VAL INT number, width)
  IF
    width < 0
      STOP
    TRUE
      [ 11 ]BYTE digits: -- 11 characters in MOSTNEG INT32 = -2147483648
      INT length:
      SEQ
        INTTOSTRING (length, digits, number)
        IF
          length < width
            SEQ
              SEQ i = len FOR (width - length)
                str[i] := ' '
              len := len + width
          TRUE
            len := len + length
        SEQ i = 1 FOR length
          str[len - i] := digits[length - i]
:
--}}}
--{{{  append.hex.int
--* Convert an integer into its representation as ASCII hexadecimal
-- characters and write this into a given string.
--
-- If str overflows then this routine acts as an invalid process. The
-- conversion of number includes a # as the first character, so that
-- the representation is always ( width + 1 ) characters. Any
-- hexadecimal characters which are letters will be in upper case.
--
-- @param len on entry: the index of str at which the first character
--   of the ASCII hexadecimal of number is to be written; on exit: the
--   index of str immediately after where the last character of the
--   ASCII hexadecimal of number was written, or SIZE str if this last
--   character was written into the last positon of str
-- @param str the string into which the hexadecimal ASCII form of
--   number is to be written
-- @param number the integer to be converted to an ASCII hexadecimal
--   representation and then written into str
-- @param width the field width of the ASCII hexadecimal representation
--   of number: if number cannot be represented in width characters
--   then the representation is truncated at the left as necessary;
--   otherwise the representation is padded on the left with 0's or F's
--   to make up width characters; it is an error if width is negative
PROC append.hex.int (INT len, []BYTE str, VAL INT number, width)
  IF
    width < 0
      STOP
    TRUE
      -- assume 'worst' case of INT requiring space for 8 hex digits, because
      -- this routine must cope with INTs of both 16 and 32 bits.
      VAL nibbles.per.word IS (32 / 4): -- a nibble is 4 bits (one hex digit)
      [nibbles.per.word]BYTE digits:
      INT length, pos, sig.digits:
      SEQ
        HEXTOSTRING (length, digits, number)
        str [len] := '#'
        --{{{  leading digit fill
        IF
          width <= length
            SEQ
              pos := 1
              sig.digits := width
          TRUE
            --{{{  pad at left
            BYTE fill.digit:
            SEQ
              IF
                number < 0
                  fill.digit := 'F'
                TRUE
                  fill.digit := '0'
              pos := width - length
              SEQ i = 1 FOR pos
                str [len + i] := fill.digit
              pos := pos + 1
              sig.digits := length
            --}}}
        --}}}
      
        [str FROM (len + pos) FOR sig.digits] := [digits FROM (length -
             sig.digits) FOR sig.digits]
        len := len + (width + 1)  -- the 1 takes account of the '#'
:
--}}}
