Hello, Thomas; hello, everybody!
According to Thomas Tan:
How does writeln(astring) work,
I am not sure whether I understand your question ...
To use `writeln', just do
writeln ( MyIntegerValue : 6, MyRealValue : 10 : 4, MyStringValue : 7 );
to get
42 3.1415 Hallo!
or
writeln ( 'Answer = ', MyIntegerValue );
to get
Answer = 42
If you want to know how `writeln' works internally, please look at the GPC source, file `rts.c', and in the subdirectory `rts' at the files `rts-write.c' and `rts-wrtinc.c'. If you have more questions about that, please post them on this list.
is the string null terminating?
No, but GPC has an additional string type `CString' (or `PChar' for BP compatibility) which *is* null-terminated. If you have, for example, a null-terminated string you want to pass to an external function that wants to have such a string as a parameter (this holds for many external functions written in C), you can use `CString' as follows:
Program Environment;
(*$X+*) (* Enable "extended syntax" if you want to use `CString' *)
Function SetEnv ( Name, Value: CString; overwrite: Integer ): Integer; C; Function GetEnv ( Name: CString ): CString; C;
Var S: CString;
begin SetEnv ( 'TEST_ENV', 'OK', 1 ); S:= GetEnv ( 'TEST_ENV' ); writeln ( S ); end.
If so, what is the character of null?
Not too surprisingly, it is `chr ( 0 )' or `#0'. :-) For `CString'. GPC's native `String' is *not* null-terminated.
And to answer your implicit question about GPC string internals: GPC's native `String' is a special case of a "schema type". It looks like a record internally:
Type String ( n: Integer ) = record Capacity, length: Integer; (* 8 bytes *) data: packed array [ 1..n ] of Char; (* n bytes *) end (* String *);
(* Remark: The above is a perfectly valid type declaration in GNU Pascal or any other compiler that supports Extended Pascal's schema types. It is, however, not identically the same as GPC's `String' since the built-in string functions only work on the built-in string type, but it has the same structure in memory. *)
When you declare a string variable with "Var Foo: String ( 42 )" (* Now you see where the round parentheses come from. ;*), the "record field" `Capacity' gets the value 42 assigned, while `length' and `data' remain undefined until you assign a value to the string. You can access a string's capacity with `Foo.capacity' just like a record field.
For dynamical allocation of strings, you can define "Type StringPtr = ^String" *without* a specified capacity and then give it when `New'ing the variable.
Program Test;
Type StringPtr = ^String;
Var Foo: StringPtr;
begin New ( Foo, 1042 ); (* allocate a String of maximum length 1042 *) Foo^:= 'Hello, world!'; writeln ( Foo^.Capacity ); (* yields "1024" *) writeln ( Foo^ ); (* yields "Hello, world!" *) Dispose ( Foo ); end.
In addition to these features of Extended Pascal, GPC supports the following extensions:
Type StringPtr = ^String;
Var Foo: StringPtr;
Foo:= @'Hello, world!'; (* let `Foo' point to a string constant *)
Foo:= New ( StringPtr, 42 ); (* let `New' act as a function *)
If you want to contribute to the GNU Pascal project, feel free to improve the existing documentation by adding the things I wrote above (and more;-). If you do so, please do not forget to post to this list what you are doing so you can coordinate with others who are currently working on the same field.
Hope this helps,
Peter
Dipl.-Phys. Peter Gerwinski, Essen, Germany, free physicist and programmer peter.gerwinski@uni-essen.de - http://home.pages.de/~peter.gerwinski/ [971005] maintainer GNU Pascal [971001] - http://home.pages.de/~gnu-pascal/ [971005]