Subject: Re: How to translate this stdio code to netbsd?
To: Mark W. Eichin <eichin@kitten.gen.ma.us>
From: Carsten Hammer <chammer@phyhammer>
List: current-users
Date: 03/12/1996 13:06:35
Operating System: NetBSD 1.1A amiga
MIME-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit
Content-Length: 3153      

> In any case, in order to answer the question, we'd probably need to
> see more of the code in question; what is it *doing* with those fields
> and how could it be handled with actual POSIX stdio interfaces...
> 

ok:)

It is part of the Geomview/OOGL Release 1.5 and i found this code
in Geomview/src/lib/oogl/util/futil.c.
It should work on SGI,NeXT,Dec Alpha,Linux and HPUX if i understand
it right.

I dont dare to send more of this code on this list. If you want
to help me make geomview work on NetBSD (this is not the only thing
that doesnt work..) it may be obtained via anonymous ftp from geom.umn.edu.

ciao
Carsten

/*
 * Given a file pointer, return a string attempting to show the context
 * of its current position.  If no data is available, returns the empty string.
 */  
char *
fcontext(register FILE *f)
{
    static char *cont = NULL;
    static char dflt[] = "";
    char buf[1024];
    int npre, npost, nlpre, nlpost, tab, len;
    int predots = 4, postdots = 4;
    register char *p, *q;       
    char *lastline, *lastnonblank;
    char *base, *ptr;
    int cnt;    

    if(f == NULL)
        return dflt;
    if(feof(f))
        return "> END OF FILE\n";
#ifdef __linux__
    base = (char *)f->_IO_read_base;
    ptr = (char *)f->_IO_read_ptr;
    cnt = ptr - base;
#else
    base = (char *)f->_base; 
    ptr = (char *)f->_ptr;
    cnt = f->_cnt;
#endif
    if(cnt <= 0 || base == NULL || ptr == NULL)
        return dflt;

    p = ptr;
    for(npre = nlpre = 0; --p >= base && npre < 128; npre++) {
        if(*p == '\n') {
            if(++nlpre > 2 || npre > 60) {
                predots = 0;
                break;
            }
        } else if(*p & 0x80 || *p == 0)         /* binary data? */
            break;
    }
    strcpy(buf, "> ... ");
    q = buf + 2 + predots;
    tab = 2 + predots;
    for(p = ptr - npre; p < ptr; ) {
        switch(*q++ = *p++) {
        case '\n': case '\r':   *q++ = '>'; *q++ = ' '; tab = 2; break;
        case '\t':              tab += 8-(tab&7); break;
        default:                tab++;
        }
    }
    len = npre;
    npost = nlpost = 0;
    lastline = lastnonblank = q;
    for(p = ptr;  p < ptr + cnt && len < 128;  len++, q++) {
        *q = *p++;
        if(*q == '\n') {
            if(nlpost == 0) {
                while(--tab > 0) *++q = '-';    /* Point ---^ to error */
                *++q = '^'; *++q = '\n';
            }
            if((++nlpost >= 2 || len > 80) && len > 32) {
                postdots = 0;
                break;
            }
            lastline = q;
            *++q = '>'; *++q = ' ';
        } else if(*q & 0x80 || *q == 0)         /* Binary data */
            break;
        else if(isprint(*q))
            lastnonblank = q;
    }
    if(postdots && lastnonblank < lastline) {
        q = lastline;           /* Suppress trailing white space */
        postdots = 0;           /* to avoid final ``> ...'' */
    }
    strcpy(q, " ...\n" + 4-postdots);
    if(nlpost == 0) {
        q += strlen(q);
        while(--tab > 0) *q++ = '-';
        strcpy(q, "^\n");
    }
    if(cont) free(cont);
    return (cont = strdup(buf));
}