Is there a mechanism in GPC to pass a variable number of parameters to a Pascal procedure (and to know how many they are?). I would like to implement something like the C "sprintf()" in Pascal.
Any clue would be welcome.
Regards
Pascal Viandier
Pascal Viandier wrote:
Is there a mechanism in GPC to pass a variable number of parameters to a Pascal procedure (and to know how many they are?).
No.
I would like to implement something like the C "sprintf()" in Pascal.
Not necessary. WriteStr is built-in already.
Frank
Thanks for this quick reply.
-----Message d'origine----- De : gpc-owner@gnu.de [mailto:gpc-owner@gnu.de] De la part de Frank Heckenbach Envoyé : March 14, 2006 10:52 À : gpc@gnu.de Objet : Re: Variable number of parameters
Pascal Viandier wrote:
Is there a mechanism in GPC to pass a variable number of parameters to a
Pascal
procedure (and to know how many they are?).
No.
I would like to implement something like the C "sprintf()" in Pascal.
Not necessary. WriteStr is built-in already.
There is no description or example for WriteStr entry in the GPC documentation. Is it possible to make something like sprintf(s, "%04d", i) with WriteStr, i.e. with leading zeroes?
Regards
Pascal Viandier
Frank
-- Frank Heckenbach, frank@g-n-u.de, http://fjf.gnu.de/, 7977168E GPC To-Do list, latest features, fixed bugs: http://www.gnu-pascal.de/todo.html GPC download signing key: ACB3 79B2 7EB2 B7A7 EFDE D101 CD02 4C9D 0FE0 E5E8
Pascal Viandier wrote:
Pascal Viandier wrote:
Is there a mechanism in GPC to pass a variable number of parameters to a
Pascal
procedure (and to know how many they are?).
No.
I would like to implement something like the C "sprintf()" in Pascal.
Not necessary. WriteStr is built-in already.
There is no description or example for WriteStr entry in the GPC documentation. Is it possible to make something like sprintf(s, "%04d", i) with WriteStr, i.e. with leading zeroes?
Not with WriteStr. Though you could pad with spaces (i : 4), and then replace spaces by zeros (StrReplace in stringutils.pas or your own way).
FormatString should be able to do it. It doesn't yet as the current implementation is not much more than a stub (it was done in a hurry ;-).
BTW, this part of FormatString is implemented in Pascal (InternalFormatString in p/rts/string2.pas), so perhaps someone who doesn't like C programming might want to help here ...
Frank
-----Message d'origine----- De : gpc-owner@gnu.de [mailto:gpc-owner@gnu.de] De la part de Frank Heckenbach Envoyé : March 14, 2006 11:37 À : gpc@gnu.de Objet : Re: RE : Variable number of parameters
Pascal Viandier wrote:
Pascal Viandier wrote:
Is there a mechanism in GPC to pass a variable number of parameters to a
Pascal
procedure (and to know how many they are?).
No.
I would like to implement something like the C "sprintf()" in Pascal.
Not necessary. WriteStr is built-in already.
There is no description or example for WriteStr entry in the GPC
documentation.
Is it possible to make something like sprintf(s, "%04d", i) with WriteStr,
i.e.
with leading zeroes?
Not with WriteStr. Though you could pad with spaces (i : 4), and then replace spaces by zeros (StrReplace in stringutils.pas or your own way).
FormatString should be able to do it. It doesn't yet as the current implementation is not much more than a stub (it was done in a hurry ;-).
Is there an example of what FormatString can do already and how to call it? The FormatString entry in the documentation is almost empty and there is no demo program for it. I tried it but found only that the character '%' followed by any letter is used as a place holder for remaining parameters and the letter is not used.
BTW, this part of FormatString is implemented in Pascal (InternalFormatString in p/rts/string2.pas), so perhaps someone who doesn't like C programming might want to help here ...
Reading the source code did not help much. What is the character '@' used for in the format string?
Regards
Pascal Viandier
Frank
-- Frank Heckenbach, frank@g-n-u.de, http://fjf.gnu.de/, 7977168E GPC To-Do list, latest features, fixed bugs: http://www.gnu-pascal.de/todo.html GPC download signing key: ACB3 79B2 7EB2 B7A7 EFDE D101 CD02 4C9D 0FE0 E5E8
Pascal Viandier wrote:
FormatString should be able to do it. It doesn't yet as the current implementation is not much more than a stub (it was done in a hurry ;-).
Is there an example of what FormatString can do already and how to call it? The FormatString entry in the documentation is almost empty and there is no demo program for it.
Not yet (as I said, done in a hurry), only a few test programs, in particular fjf629[efg].pas. But when you understood it, feel free to send us some. :-)
I tried it but found only that the character '%' followed by any letter is used as a place holder for remaining parameters and the letter is not used.
Yes, because GPC has type information itself already, i.e. it's not necessary to distinguish between %s for strings and %i for numbers.
BTW, this part of FormatString is implemented in Pascal (InternalFormatString in p/rts/string2.pas), so perhaps someone who doesn't like C programming might want to help here ...
Reading the source code did not help much. What is the character '@' used for in the format string?
To specify a different argument to write. E.g. %@2s will output the 2nd parameter, instead of the next one. This is sometimes needed in i18n.
BTW, I see that glibc added a different syntax for the same purpose, apparently later than we did, namely %2$s. Perhaps we should consider changing it (e.g., to make things easier for i18n translators), if the %@2s syntax isn't in widespread use yet.
That basically all it does now. As I wrote, it doesn't have padding options yet, though space-padding and precision of reals can be given as in Write statements, e.g. FormatString ('%s', Pi : 10 : 5). (But we should add at least space- and zero padding facilities in the format string, indeed.)
Frank
-----Message d'origine----- De : gpc-owner@gnu.de [mailto:gpc-owner@gnu.de] De la part de Frank Heckenbach Envoyé : March 15, 2006 05:33 À : gpc@gnu.de Objet : Re: RE : RE : Variable number of parameters
Pascal Viandier wrote:
FormatString should be able to do it. It doesn't yet as the current implementation is not much more than a stub (it was done in a hurry ;-).
Is there an example of what FormatString can do already and how to call it? The FormatString entry in the documentation is almost empty and there is no
demo
program for it.
Not yet (as I said, done in a hurry), only a few test programs, in particular fjf629[efg].pas. But when you understood it, feel free to send us some. :-)
I tried it but found only that the character '%' followed by any letter is used as a place holder for remaining parameters and the letter is
not
used.
Yes, because GPC has type information itself already, i.e. it's not necessary to distinguish between %s for strings and %i for numbers.
BTW, this part of FormatString is implemented in Pascal (InternalFormatString in p/rts/string2.pas), so perhaps someone who doesn't like C programming might want to help here ...
Reading the source code did not help much. What is the character '@' used
for in
the format string?
To specify a different argument to write. E.g. %@2s will output the 2nd parameter, instead of the next one. This is sometimes needed in i18n.
BTW, I see that glibc added a different syntax for the same purpose, apparently later than we did, namely %2$s. Perhaps we should consider changing it (e.g., to make things easier for i18n translators), if the %@2s syntax isn't in widespread use yet.
That basically all it does now. As I wrote, it doesn't have padding options yet, though space-padding and precision of reals can be given as in Write statements, e.g. FormatString ('%s', Pi : 10 : 5). (But we should add at least space- and zero padding facilities in the format string, indeed.)
What do you think about the idea of calling sprintf() from InternalFormatString after appropriate transformation of the format string and adaptation of the parameters?
After all, both have almost the same purpose with the advantage for sprintf for the formatting we would like to add to InternalFormatString.
I think the challenging part - for me - would be to pass the arguments to sprintf() since I do not understand yet how the parameters passing mechanism works.
You (Frank) wrote previously that one cannot make a Pascal function accepting a variable number of parameters. At my surprise FormatString is exactly that.
Am I right, somewhat right or wrong? Did I miss something?
Regards
Pascal
Pascal Viandier wrote:
That basically all it does now. As I wrote, it doesn't have padding options yet, though space-padding and precision of reals can be given as in Write statements, e.g. FormatString ('%s', Pi : 10 : 5). (But we should add at least space- and zero padding facilities in the format string, indeed.)
What do you think about the idea of calling sprintf() from InternalFormatString after appropriate transformation of the format string and adaptation of the parameters?
I don't like it. I prefer to use C functions only where necessary (such as portable system interfaces or 3rd party libraries). String formatting is a high level task that can be implemented in Pascal.
One practical advantage is that we avoid getting system-dependent more than necessary. Some C libraries have some extra features in *printf, and some old ones may not even support printing long (e.g., 64 bit) integers -- this was the state of affairs some 8 years ago when I rewrote the `Write{,Ln,Str}' routines from *printf to self-made routines. Even if that might not apply today (and I'm not sure, since we don't want to support only bleeding-edge systems), other extensions do vary (and probably will in the future), and having an output that works on one system and not the other (and not because of range limitations, just different features in the C library) is not something I'd like to see.
After all, both have almost the same purpose with the advantage for sprintf for the formatting we would like to add to InternalFormatString.
I think the challenging part - for me - would be to pass the arguments to sprintf() since I do not understand yet how the parameters passing mechanism works.
It may be possible. But I'd rather spend this effort writing a better Pascal (Internal)FormatString.
You (Frank) wrote previously that one cannot make a Pascal function accepting a variable number of parameters. At my surprise FormatString is exactly that.
FormatString is not a regular Pascal function. It's a compiler built-in that's expanded to a sequence of "magic" RTS calls, one of the last of them being InternalFormatString. At this point, the variable arguments have already been pre-converted to strings and put in an array (`Strings^'), so the function only needs to deal with an array of variable size. (Admittedly, it currently doesn't use one of the standard ways (conformant array or schema) or BP open arrays but a formally-unbounded array, but we may change this, and it's unrelated to the "varargs" question.)
Frank
FormatString is not a regular Pascal function. It's a compiler built-in that's expanded to a sequence of "magic" RTS calls, one of the last of them being InternalFormatString. At this point, the variable arguments have already been pre-converted to strings and put in an array (`Strings^'), so the function only needs to deal with an array of variable size. (Admittedly, it currently doesn't use one of the standard ways (conformant array or schema) or BP open arrays but a formally-unbounded array, but we may change this, and it's unrelated to the "varargs" question.)
I would be interested to modify InternalFormatString to handle padding.
I propose to replace the unused character after the '%' by the character used to pad the corresponding field (if it is not alphabetic). This way, existing code with %d, %s, ... will continue to work as before.
Doing this s := FormatString('Display 00042: %0', 42:5); would produce 'Display 00042: 00042'. s := FormatString('Display ***Hello: %*', 'Hello':8); would produce 'Display ***Hello: ***Hello'.
Please give me your advice. I won't do anything with approval.
Other related question: Is there a way I can test the modification to InternalFormatString without installing the runtime library system-wide? (just in case it does not work ;-)
Kind regards
Pascal
Pascal Viandier wrote:
FormatString is not a regular Pascal function. It's a compiler built-in that's expanded to a sequence of "magic" RTS calls, one of the last of them being InternalFormatString. At this point, the variable arguments have already been pre-converted to strings and put in an array (`Strings^'), so the function only needs to deal with an array of variable size. (Admittedly, it currently doesn't use one of the standard ways (conformant array or schema) or BP open arrays but a formally-unbounded array, but we may change this, and it's unrelated to the "varargs" question.)
I would be interested to modify InternalFormatString to handle padding.
I propose to replace the unused character after the '%' by the character used to pad the corresponding field (if it is not alphabetic). This way, existing code with %d, %s, ... will continue to work as before.
Doing this s := FormatString('Display 00042: %0', 42:5); would produce 'Display 00042: 00042'. s := FormatString('Display ***Hello: %*', 'Hello':8); would produce 'Display ***Hello: ***Hello'.
Padding with arbitrary characters seems an interesting feature. Your syntax is one possibility, but it could be taken to mean that %s would pad with s characters (not very useful in most cases, but perhaps sometimes). Therefore I'd rather suggest some explicit "padding indicator", something like %&*s where & means "pad with" and * is the character to pad with. Note that & is a completely random quick choice by me and probably not the best one. We should look if some C library (or even some other language with similar functionality) has something like this, and if so (and it's not too outlandish ;-), probably try to be compatible. If not, we should look which character is not used for other purposes elsewhere. I haven't looked carefully, so I can't tell ATM.
However, for the common case of 0-padding, we might support a simpler format such as C's %05s (width 5, zero-padded) in addition.
Note that ofr these purposes it's probably better to have the padding specified in the format string, i.e.:
FormatString ('%05s', x)
rather than
FormatString ('%0s', x : 5)
as in the latter case the padding would be done before InternalFormatString, so it couldn't tell the padding spaces (which it should convert to 0's) from leading spaces in x (if x is a string) which should not be converted.
Of course, we can't stop the user from writing x : 5, but we can provide padding in the format string, so it's up to the user which one he uses.
Please give me your advice. I won't do anything with approval.
Without, I hope. ;-)
Other related question: Is there a way I can test the modification to InternalFormatString without installing the runtime library system-wide? (just in case it does not work ;-)
You'll have to rebuild the RTS, of course, but you probably can use it without installing by giving it explicitly on the command line, e.g.:
gpc myprog.pas .../build/gcc/libgpc.a
This should take precedence over the implicit -lgpc. (But please test first with a clearly visible change, so you won't waste time searching why your changes have no effect.)
Frank
-----Message d'origine----- De : gpc-owner@gnu.de [mailto:gpc-owner@gnu.de] De la part de Frank Heckenbach Envoyé : March 16, 2006 14:43 À : gpc@gnu.de Objet : Re: FormatString (was Variable number
Pascal Viandier wrote:
FormatString is not a regular Pascal function. It's a compiler built-in that's expanded to a sequence of "magic" RTS calls, one of the last of them being InternalFormatString. At this point, the variable arguments have already been pre-converted to strings and put in an array (`Strings^'), so the function only needs to deal with an array of variable size. (Admittedly, it currently doesn't use one of the standard ways (conformant array or schema) or BP open arrays but a formally-unbounded array, but we may change this, and it's unrelated to the "varargs" question.)
I would be interested to modify InternalFormatString to handle padding.
I propose to replace the unused character after the '%' by the character
used to
pad the corresponding field (if it is not alphabetic). This way, existing
code
with %d, %s, ... will continue to work as before.
Doing this s := FormatString('Display 00042: %0', 42:5); would produce 'Display 00042: 00042'. s := FormatString('Display ***Hello: %*', 'Hello':8); would produce 'Display ***Hello: ***Hello'.
Padding with arbitrary characters seems an interesting feature. Your syntax is one possibility, but it could be taken to mean that %s would pad with s characters (not very useful in most cases, but perhaps sometimes). Therefore I'd rather suggest some explicit "padding indicator", something like %&*s where & means "pad with" and * is the character to pad with. Note that & is a completely random quick choice by me and probably not the best one. We should look if some C library (or even some other language with similar functionality) has something like this, and if so (and it's not too outlandish ;-), probably try to be compatible. If not, we should look which character is not used for other purposes elsewhere. I haven't looked carefully, so I can't tell ATM.
That's a good suggestion. I will look on my side too.
However, for the common case of 0-padding, we might support a simpler format such as C's %05s (width 5, zero-padded) in addition.
Note that ofr these purposes it's probably better to have the padding specified in the format string, i.e.:
FormatString ('%05s', x)
rather than
FormatString ('%0s', x : 5)
as in the latter case the padding would be done before InternalFormatString, so it couldn't tell the padding spaces (which it should convert to 0's) from leading spaces in x (if x is a string) which should not be converted.
Of course, we can't stop the user from writing x : 5, but we can provide padding in the format string, so it's up to the user which one he uses.
At first glance I would agree with this. But it introduces a possibility of conflicts between the format string and the width indicator of the parameter. What should do FormatString ('%05s', x : 8) or worse FormatString ('%08s', x : 5) in a logical way? This has also the inconvenience of limiting the padding capability to '0' unless we allow '%x8s' to pad with 'x' like in some accounting receipts or cheques. An other interesting example would be FormatString ('%-', '-':80 ); which makes a string of 80 '-'. I know there are many other ways to this but I find this one nice and easy.
Please give me your advice. I won't do anything with approval.
Without, I hope. ;-)
Oups! As you see, my Pascal is better than my English (I hope so - for the Pascal -;-)
Other related question: Is there a way I can test the modification to InternalFormatString without installing the runtime library system-wide? (just in case it does not work
;-)
You'll have to rebuild the RTS, of course, but you probably can use it without installing by giving it explicitly on the command line, e.g.:
gpc myprog.pas .../build/gcc/libgpc.a
This should take precedence over the implicit -lgpc. (But please test first with a clearly visible change, so you won't waste time searching why your changes have no effect.)
Thanks for the hint.
Regards
Pascal
Pascal Viandier wrote:
However, for the common case of 0-padding, we might support a simpler format such as C's %05s (width 5, zero-padded) in addition.
Note that ofr these purposes it's probably better to have the padding specified in the format string, i.e.:
FormatString ('%05s', x)
rather than
FormatString ('%0s', x : 5)
as in the latter case the padding would be done before InternalFormatString, so it couldn't tell the padding spaces (which it should convert to 0's) from leading spaces in x (if x is a string) which should not be converted.
Of course, we can't stop the user from writing x : 5, but we can provide padding in the format string, so it's up to the user which one he uses.
At first glance I would agree with this. But it introduces a possibility of conflicts between the format string and the width indicator of the parameter. What should do FormatString ('%05s', x : 8)
First pad x to 8 chars with spaces, then pad the result to 5 chars with 0's. Since the first gives already 8 chars (minimum), the latter won't do anything, i.e. it's equivalent to just '%s'.
or worse FormatString ('%08s', x : 5)
Pad x to 5 chars with spaces, then to 8 chars with zeros. This actually has a non-trivial effect (maybe useful to someone).
There isn't actually much choice what to do about : padding, unless we implement it much differently (and much more complicated, it seems). If users use both forms of padding at the same time, they should know what they're doing (tm). :-)
This has also the inconvenience of limiting the padding capability to '0' unless we allow '%x8s' to pad with 'x' like in some accounting receipts or cheques.
As I wrote before, the possibility of padding with an arbitrary character seems interesting. I just think we need a special indicator for it, as otherwise any character with a different meaning could not be used for padding. So e.g. %&x8s with my completely random choice of & could work for the receipt.
An other interesting example would be FormatString ('%-', '-':80 ); which makes a string of 80 '-'. I know there are many other ways to this but I find this one nice and easy.
Also interesting, though (see above), this won't work with : padding, but with format string padding, such as:
FormatString ('%&-80s', '')
(The second argument can be the empty string actually, but '-' also works, of course.)
Frank
Padding with arbitrary characters seems an interesting feature. Your syntax is one possibility, but it could be taken to mean that %s would pad with s characters (not very useful in most cases, but perhaps sometimes). Therefore I'd rather suggest some explicit "padding indicator", something like %&*s where & means "pad with" and * is the character to pad with. Note that & is a completely random quick choice by me and probably not the best one. We should look if some C library (or even some other language with similar functionality) has something like this, and if so (and it's not too outlandish ;-), probably try to be compatible. If not, we should look which character is not used for other purposes elsewhere. I haven't looked carefully, so I can't tell ATM.
That's a good suggestion. I will look on my side too.
I found some interesting documentation:
- A specialized language but the documentation is interesting and they implement padding with arbitrary character http://www.symbian.com/developer/techlib/v8.1adocs/doc_source/guide/Base-sub... em-guide/N1007A/BuffersAndStrings/Descriptors/DescriptorsGuide3/FormatStringSynt ax.guide.html
- common lisp We may get something out of this http://www.supelec.fr/docs/cltl/clm/node200.html
- Java Similar to sprintf http://java.sun.com/j2se/1.5.0/docs/api/java/util/Formatter.html
- Php Implement padding with arbitrary character but I am pretty sure we wont use the same ;-) http://www.usphp.com/function.sprintf.html
Other documentation I found shows that most languages mimic C sprintf()
Regards
Pascal
Pascal Viandier wrote:
Padding with arbitrary characters seems an interesting feature. Your syntax is one possibility, but it could be taken to mean that %s would pad with s characters (not very useful in most cases, but perhaps sometimes). Therefore I'd rather suggest some explicit "padding indicator", something like %&*s where & means "pad with" and * is the character to pad with. Note that & is a completely random quick choice by me and probably not the best one. We should look if some C library (or even some other language with similar functionality) has something like this, and if so (and it's not too outlandish ;-), probably try to be compatible. If not, we should look which character is not used for other purposes elsewhere. I haven't looked carefully, so I can't tell ATM.
That's a good suggestion. I will look on my side too.
I found some interesting documentation:
- A specialized language but the documentation is interesting and they implement
padding with arbitrary character http://www.symbian.com/developer/techlib/v8.1adocs/doc_source/guide/Base-sub... em-guide/N1007A/BuffersAndStrings/Descriptors/DescriptorsGuide3/FormatStringSynt ax.guide.html
"The full aligned-conversion is verbose, but in addition to the zero and space characters, it permits non-numeric characters to be specified as the character." -- So, anything except 1-9? Seems strage. (PS: Nice, short URL. ;-)
- Php Implement padding with arbitrary character but I am pretty sure we wont
use the same ;-) http://www.usphp.com/function.sprintf.html
Single quotes are not really most practical for us, no. ;-)
- common lisp We may get something out of this
Also single quotes!?
- Java Similar to sprintf
http://java.sun.com/j2se/1.5.0/docs/api/java/util/Formatter.html
Yes, I don't see any arbitrary character padding there.
PS: I see another problem. Our existing `@2' might conflict with padding (parameter #2, pad width 10 -> `@210'), so either we must require it to come after padding (if any), or change its syntax (then perhaps to glibc-compatible `2$', which must then always come before padding).
Frank