NED@YMIR.BITNET.UUCP (02/24/87)
I have been working on porting Nelson Beebe's family of TeX previewers to VMS using VAX C (yes, they seem to be working, no, I have not tested them enough to be sure they work correctly). I have encountered two problems and solutions while using VAX C that I thought would be of interest to this group. The first problem is the use of standard I/O functions on non-streamlf files. In particular, I wanted to use the fseek function on files with fixed length 512 byte records. (My set of .PXL files for TeX are written in this format. I cannot change the format without breaking all of my other DVI programs, and I do not want to have to duplicate 100,000 blocks of files.) VAXCRTL is very clever and uses block I/O on streamlf files. When it sees another file type it uses a fancy sort of record I/O instead. The result is that fseek doesn't go where you want it to when using record I/O. I wanted to FORCE C to use block I/O on a non-streamlf file. I could not find a way to do this in the documentation, so I started perusing the ufiche and I found a really neat feature. It turns out that if you include the special attribute "ctx=stm" in a call to fopen the file will be opened for block I/O UNCONDITIONALLY. For example: fd = fopen(filename,mode,"ctx=stm"); This will work for ANY sort of sequential file. Of course, if you open a regular variable length record file you're going to get the record length fields and all the other junk that's in there, but its just the ticket for reading fixed length record files in a reasonable fashion. The actual effect of this file attribute is to set some bit in the CTX field of the file's RAB. This "user" field is used by C to store all sorts of status bits. This feature was added in November 1985, and my C manual is dated April 1985 (V2.0), so its not suprising that is does not appear in the documentation. However, the release notes do not mention it either (at least not that I can find). I presume that it will be documented in some future release, or perhaps I simply missed seeing it (although I don't think so). I certainly hope it doesn't disappear in some future release! On to the second problem. Beebe's DVI converters use the ungetc standard I/O function in several places. However, a nasty bug showed up in ungetc -- it cannot "push back" a character with an ASCII value above 127. Such characters are ALL interpreted as EOF characters, and you cannot unget an EOF (I don't know why but you cannot). This behavior is not documented as far as I can see, and it certainly does not correspond to ungetc in most other C implementations. I pondered this for a while and finally decided to write my own ungetc that would work with any character. A listing of this routine is given below. I had to diddle an assortment of internal C data structures so the routine may break in some future release, but it works fine with V2.2 of C. Ned Freed ned@ymir.bitnet -------------------------------------------------------------------------- .title vmsungetc - Replacement for VAX C ungetc routine $FABDEF fcb_l_buffcnt = 0 fcb_l_buffptr = 4 fcb_l_buffadr = 8 .entry vmsungetc,^m<r2,r3,r4,r5,r6,r7,r8,r9,r10,r11> movl 8(ap),r7 movl (r7),r7 movl fcb_l_buffptr(r7),r1 cmpl r1,fcb_l_buffadr(r7) bleq 10$ movb 4(ap),-(r1) movl r1,fcb_l_buffptr(r7) incl fcb_l_buffcnt(r7) 10$: ret .end