{ -*- mode: pascal; … -*-

pascal include file for c library functions

}


{ string functions
  ----------------

to use these string functions, declare these c string pointer types:

   cstring  =  array[1..maxint] of char;
   cstringPtr  =  ^cstring;

and declare some variables:

    myString : packed array[1..MaxStringSize] of char;
    sp       : cstringPtr;       -- use this to access the c library

The c library uses pointers to strings, so to get a pointer to myString,
do someting like this:

     sp := getcstrPtr(myString);

Now sp points to myString, and sp^[1] is the same as myString[1]. It's not a
copy it's 2 different ways of seeing the same string - if you change one
you'll see the new value in the other.

Note:
- in pascal, strings index from 1, so the first character of a cstringptr
  is also index 1. As mentioned above myString[1] refers to the same
  character as sp^[1].  If you've ever programmed in c you'll see that
  pascal does not use the c convention where strings start at index 0.

- c strings are null terminated, ie chr(0) indicates the end of the string.
  You need to put this in this yourself

- you need to make sure that the string you are using is big enough to hold
  the text you are putting into it.

- a c string is a pointer to memory that has not been allocated with new.
  pascal's memory debug identifies this as rouge memory and issues a fatal
  error whenever it sees a cstring being used.
  You can use c strings only with pascal memory debug disabled, ie when
  debug is disabled where the program keyword is.  See the memory debug
  description in the user guide for more information.

You can now use the c string pointer for the arguments to the c library
functions.

simple example:

   myString := 'abc       ';     -- pascal mystring is packed array of 10 chars
   sp := getcstrPtr(myString);
   sp^[3] := chr(0);             -- null terminate string after 3rd char
   writeln('string length is ', strlen(sp^[0]) );

Notes:
- to null terminate the string, we could just as well have written

      myString[4] := chr(0);        -- another way of doing the same thing

- the argument to the string function (strlen in this example) is the first
  character where we want to start using the string - it need not be the
  start of the buffer.  If you want to copy text into the middle of a string,
  say to copy characters spSrc[2...] of the source to characters spDest[6...]
  of the destination, use code like this

    strcpy(spDest^[6], spSrc^[2]);

- it is your responsibility to ensure that the argument to the string
  function is the first character of a valid string.  Nothing will stop
  you calling you calling the function with a character on its own - no
  compiler warnings, no runtime diagnostics, nothing.  Your program will
  very likely crash, of course, possibly with no indication as to why.
  This is the c world, and it is assumed you know what you are doing.

there is some test code in the file tclib.pas you can use as examples.

}

{: return a c string pointer that points to a pascal string}
function getcstrPtr(var ps : packed array[lo..hi :integer] of char) : cstringPtr {@@ inline @@};
begin
   getcstrPtr := nil;   {redundant, but compiler error if function result not assigned}
{@@
 return ps_2c;
@@}
end;

{: return the length of a c string - how many characters up to the null character?}
Function Strlen(var firstCh : char) : integer; external;
{@@
inline int Strlen(unsigned char *s) {return strlen(s);}
@@}

{: copy a c string from source to destination.
   src & dst are the first charcters of the strings}
procedure Strcpy(var dst, src : char)  {@@ inline @@} ;
begin
{@@
    (void)strcpy(dst_2, src_2);
@@}
end { Strcpy };


{: append a c string from source to the end of destination.
   src & dst are the first charcters of the strings}
procedure Strcat(var dst, src : char) {@@ inline @@} ;
begin
{@@
    (void)strcat(dst_2, src_2);
@@}
end { Strcat };


{: compare 2 c strings, return
        0  : the strings are identical
        1  : s1 > s2
        -1 : s1 < s2
   s1 and s2 are the first charcters of the strings}
function Strcmp(var s1, s2 : char) : integer {@@ inline @@} ;
begin
      Strcmp := 0;  {dead code, prevents compiler error}
{@@
    return strcmp(s1_2, s2_2);
@@}
end { Strcat };


{: Return arc cosine of x, result is in radians }
function acos(x: real): real; external;

{: Return arc sine of x, result is in radians }
function asin(x: real): real; external;

{: Return arc tangent of y/x, result is in radians, -pi < result <= pi }
function atan2(y: real; x: real): real; external;

{: Return tangent of angle in radians }
function tan(x: real): real; external;

{: Return the hyperbolic cosine of x }
function cosh(x: real): real; external;

{: Return the hyperbolic sine of x }
 function sinh(x: real): real; external;

{: Return the hyperbolic tangent of x }
function tanh(x: real): real; external;

{: Get smallest integer >= x }
function ceil(x: real): real; external;

{: Get largest integral value <= x }
function floor(x: real): real; external;

{: return remainder x - i*y,
for largest i st remainder has same sign as x, and is closer to zero than y is }
function fmod(x: real; y: real): real; external;

{: find mantissa and exponent of x, where x = result * 2**exponent  }
function frexp(x : real; var exponent: integer): real; external;

{: Return real nr made of mantissa and exponent of two }
function ldexp(x : real; exponent: integer): real; external;

{: Return log to the base 10 of x }
function log10 (x: real ): real; external;

{: find fractional and integer parts of x}
function modf(x : real; var intPart: real): real; external;

{: Return x raised to the power y }
function pow (x: real; y: real): real; external;

{: Seed the random number generator
seedType must be unsigned = 0..maxint -- this must be defined earlier by user }
procedure srand(seed : seedType); external;

{: return a random number >= 0 }
function rand: integer; external;

{: run myproc when main program terminates.
   return value is zero if successful }
function atexit( procedure myproc ): integer; external;

{--- end of clib.inc.pas ---}
