Nick Cremelie wrote:
Not really with bindings, but anyway: There's a known bug "On IRIX work stations, _p_initfdr() must be called manually" on the To-Do list. So, I'm adding AIX there. I don't know anything about these architectures, but I agree that fixing this would be a good idea... :-/
I don't see how I can call _p_initfdr() manually. From within the Pascal program, the compiler complains when I call that function. When I try to call InitFDR (defined in p/rts/gpc.pas I thought), the compiler says:
txtfile.pas: In function `Assign': txtfile.pas:16: undeclared identifier `Initfdr' (first use this function) txtfile.pas:16: (Each undeclared identifier is reported only once txtfile.pas:16: for each function it appears in.)
So how do I call initfdr manually???
Yes, the above description for the work around is a bit too simplistic. If you want to call it from Pascal, you have to copy the declaration of InitFDR from gpc.pas, or add an "uses gpc;" to your program (however, the latter is not yet completely worked out, so it may cause some name conflicts).
As you will recall, I had problems with gpc on AIX when opening files. I made a little change in rts-file.c: I replaced line 370:
_p_generic (701); /* FDR not initialized */
with
_p_initfdr(File,filename,8,0xf);
This means: if m_SIZ(File) == 0 (indicating that _p_initfdr was not called), I call it with a standard buffersize and flags). This enables me indeed to open files for reading and writing! However, I have no clue about the impact of this change.
A clever idea! The problem is to get the parameters right. The above work for text files, but they're a bit unusual (and I wonder why GPC uses them for Input and Output).
The following are the parameters GPC uses for the different kinds of files -- however, they're subject to change in future versions, but not too soon (i.e. not until GPC version 2.1):
Text files (text): 1, 1 Typed files (file of foo): Sizeof(f^), 0 Direct typed files (file [bar..baz] of foo): Sizeof(f^), 16 Untyped files (file) (BP extension): 1, 64
For "external" files, i.e. those declared in the program header, add 4 to the last parameter. The second parameter is actually the internal file name (i.e. the name of the variable as declared in the program), but it's only used for the Standard Pascal feature of asking the user for a name for file "foo", and for some error messages.
But it seems strange to me in the first place why _p_initfdr() isn't called automatically -- after all, the compiler (util.c, function init_simple() generates code to do so). Could you generate an assembler output of your Pascal program (gpc -S), and check if it contains some calls to _p_initfdr(), and if so, what parameters are pushed before it.
But then we noticed something else: reading a string (string[255]) with readln (from file or stdin) always returned an empty string, although eoln and eof are set appropriately (so it is actually reading the file!). We checked and noticed that the argument maxlen to _p_reads in rts-rdsub.c is always zero. Question: would this be because va_arg (which gets maxlen from a variable argument list) doesn't work probably, or because the variable argument list is not set properly when calling _p_read in rts-read.c ?
Could you please check which parameters are pushed before the call to _p_read() in the assembler code of your program (or just send me the assembler file if that's easier to you)?
For another test, you could check the value of s_maxlen in the READ_STRING macro in rts-rdinc.c (with some printf) and see if it's already wrong there. (I suppose it is, but one never knows...)
Also, did you get any warnings (especially of type mismatches and the like) when compiling the RTS? This might indicate some non-portable type conversions in the C files.
Perhaps really the varargs are to blame -- I don't know much about their inner workings. I intend to get rid of them, anyway. If they're the problem here, this might be a reason to get rid of them even earlier than planned...
Frank