[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference turris::decc_bugs

Title:DEC C Problem Reporting Forum
Notice:Report DEC C++ problems in TURRIS::C_PLUS_PLUS
Moderator:CXXC::REPETETCHEON
Created:Fri Nov 13 1992
Last Modified:Fri Jun 06 1997
Last Successful Update:Fri Jun 06 1997
Number of topics:1299
Total number of notes:6249

1283.0. "Multiple calls to ungetc() fail" by SMAUG::GARROD (IBM Interconnect Engineering) Wed Mar 26 1997 20:50

    This is related to note 1009.*. But doesn't seem to be the same
    problem.
    
    Problem Description:
    
    When ungetc() is called twice in a row the second call to
    ungetc() fails.
    
    Where observed:
    ---------------
    
    OpenVMS Alpha V61 (with and without ECO ALPACRT09_061)
    OpenVMS VAX V6.1  (with and without ECO VAXACRT09_061)
    
    
    This is with a stream_lf file. ungetc() seems to work fine with VAXC.
    It also works fine on Digital UNIX.
    
    Interesting enough though it fails with VAXC in an identical way
    on OpenVMS VAX if the file is a variable length record file.
    
    (I've just received mail saying that the documentation only guarantees
     you being able to ungetc() one character. Given that I'm going to
     try and rejig my product to work in all cases. But I think I'll leave
    my note here for posterity in case it will help anybody else that
    runs over this issue. But I agree if the documentation explicitly only
    guarantees one ungetc() working then I can't call this a bug).
    
    In .1 is a program demonstrating the above behaviour.
    
    Regards,
    
    Dave
T.RTitleUserPersonal
Name
DateLines
1283.1Program to show the issueSMAUG::GARRODIBM Interconnect EngineeringWed Mar 26 1997 20:5156
This program demonstrates the problem.
    
    
#include <stdio.h>
main ()
{
FILE *fd;
int status;
int i;
char c;

/*
 * Create a scratch file
 */
fd = fopen("foo.bar", "w");
fputs("This is just a line of text\n", fd);
fclose(fd);

/*
 * Open it for read
 */
fd = fopen("foo.bar", "r");

/*
 * Suck out three characters
 */
for (i=0;  i<3;  i++)
{
    c= getc(fd);
    printf ("read character '%c'\n", c);
}

/*
 * Put one back
 */
status = ungetc('A', fd);
printf ("unget() status = %d\n", status);

/*
 * Try and suck out another character
 */
status = ungetc('B', fd);

/*
 * Oh dear looks like we've found a bug. Works with VAXC but not DECC.
 */
printf ("unget() status = %d\n", status);
if (status != 'B')
{
    printf("***ERROR***, unget() should have returned 'B', rather than %d\n", status);
    return -1;
}
c = getc(fd);
printf ("read character '%c'\n", c);
return 0;
}
1283.2Results of test runsSMAUG::GARRODIBM Interconnect EngineeringWed Mar 26 1997 21:0055
    Fails on OpenVMS Alpha V6.1 (ECO applied)
    -----------------------------------------
     
    $ cc file
    $ link file
    $ run file
    read character 'T'
    read character 'h'
    read character 'i'
    unget() status = 65
    unget() status = -1
    ***ERROR***, unget() should have returned 'B', rather than -1
     
    
    Fails on OpenVMS VAX V6.1 (ECO applied)
    ----------------------------------------
    
    $ cc file
    $ link file
    $ run file
    read character 'T'
    read character 'h'
    read character 'i'
    unget() status = 65
    unget() status = -1
    ***ERROR***, unget() should have returned 'B', rather than -1
    
    Works fine with OpenVMS VAX V6.1 (ECO applied) VAXC
    ---------------------------------------------------
    
    $ cc/vaxc file
    $ link file,sys$input/opt
    sys$share:vaxcrtl/share
    ^Z
    $ run file
    read character 'T'
    read character 'h'
    read character 'i'
    unget() status = 65
    unget() status = 66
    read character 'B'
    
    
    Works fine on Digital UNIX
    --------------------------
    
    bufcal.lkg.dec.com> cc -o file file.c
    bufcal.lkg.dec.com> file
    read character 'T'
    read character 'h'
    read character 'i'
    unget() status = 65
    unget() status = 66
    read character 'B'
    
1283.3I should have read the module header...SMAUG::GARRODIBM Interconnect EngineeringWed Mar 26 1997 21:1715
    Oh well looks like I should have read the edit header of the
    module in my product that doesn't work. I'll try using
    fsetpos() (like it does on OSF) and see if that indeed does
    work on VMS.
    
    Dave
    
    
 *   1.1-01  28-SEP-1993 Dana Porter
 *	     Unsupported code discovered when running on OSF.
 *	     Change code for OSF so that don't do 'ungetc' of more than
 *	     one character in a row.  For OSF use fsetpos to reposition
 *	     back to beginning of token.  This should work for VMS also,
 *	     but testing hasn't been done yet.
 *	     Updated version #, environment, history.
1283.4SPECXN::DERAMODan D&#039;EramoThu Mar 27 1997 14:1443
        Of course, notwithstanding what the standard says as quoted in
        my earlier reply, it is also legal for ungetc to accept more
        than one character of pushback.  If the stream is buffered,
        and if you are not positioned "before" the first character of
        the buffer, say
        
        	start of buffer: a b c d e f g
        	                      ^
        	        (current position in buffer)
        
        and if you push back what is already there ('c', 'b', 'a') and
        if that works, well, then, that would be nice, too. :-)
        
        Dan
        
         <<< TURRIS::DISK$NOTES_PACK:[NOTES$LIBRARY]DECC_BUGS.NOTE;1 >>>
                       -< DEC C Problem Reporting Forum >-
================================================================================
Note 1009.9   (P1)  ungetc broken in OpenVMS Alpha 6.2 and VAX 6.2        9 of 9
SPECXN::DERAMO "Dan D'Eramo"                         22 lines  26-MAR-1997 20:43
--------------------------------------------------------------------------------
>     Attached is a noddy problem that demonstrates the problem.
>     foo.bar is any old file with characters in it. The prgram
>     fails when it attepts to unget() the 'B' character. It returns -1
>     instead of 'B'.
        
> status = ungetc('A', fd);
> printf ("status = %d\n", status);
> status = ungetc('B', fd);
> printf ("status = %d\n", status);
        
        The standard says of ungetc
        
        	  One character of pushback is guarenteed.  If the
        	ungetc function is called too many times on the same
        	stream without an intervening read or file positioning
        	operation on that stream, the operation may fail.
        
        Unless our documentation makes more of a committment than that
        one character of pushback, then the behavior you are seeing is
        legal for ungetc.
        
        Dan