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