diff options
Diffstat (limited to 'do/fttext')
-rw-r--r-- | do/fttext | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/do/fttext b/do/fttext new file mode 100644 index 0000000000..6d6f28834f --- /dev/null +++ b/do/fttext @@ -0,0 +1,94 @@ +STR * +do_fttext(arg,TARG) +register ARG *arg; +STR *TARG; +{ + int i; + int len; + int odd = 0; + STDCHAR tbuf[512]; + register STDCHAR *s; + register STIO *stio; + + if (arg[1].arg_type & A_DONT) { + if (arg[1].arg_ptr.arg_stab == defstab) { + if (statstab) + stio = stab_io(statstab); + else { + TARG = statname; + goto really_filename; + } + } + else { + statstab = arg[1].arg_ptr.arg_stab; + str_set(statname,""); + stio = stab_io(statstab); + } + if (stio && stio->ifp) { +#if defined(STDSTDIO) || defined(atarist) /* this will work with atariST */ + fstat(fileno(stio->ifp),&statcache); + if (S_ISDIR(statcache.st_mode)) /* handle NFS glitch */ + return arg->arg_type == O_FTTEXT ? &str_no : &str_yes; + if (stio->ifp->_cnt <= 0) { + i = getc(stio->ifp); + if (i != EOF) + (void)ungetc(i,stio->ifp); + } + if (stio->ifp->_cnt <= 0) /* null file is anything */ + return &str_yes; + len = stio->ifp->_cnt + (stio->ifp->_ptr - stio->ifp->_base); + s = stio->ifp->_base; +#else + fatal("-T and -B not implemented on filehandles"); +#endif + } + else { + if (dowarn) + warn("Test on unopened file <%s>", + stab_ename(arg[1].arg_ptr.arg_stab)); + errno = EBADF; + return &str_undef; + } + } + else { + statstab = Nullstab; + str_set(statname,str_get(TARG)); + really_filename: + i = open(str_get(TARG),0); + if (i < 0) { + if (dowarn && index(str_get(TARG), '\n')) + warn(warn_nl, "open"); + return &str_undef; + } + fstat(i,&statcache); + len = read(i,tbuf,512); + (void)close(i); + if (len <= 0) { + if (S_ISDIR(statcache.st_mode) && arg->arg_type == O_FTTEXT) + return &str_no; /* special case NFS directories */ + return &str_yes; /* null file is anything */ + } + s = tbuf; + } + + /* now scan s to look for textiness */ + + for (i = 0; i < len; i++,s++) { + if (!*s) { /* null never allowed in text */ + odd += len; + break; + } + else if (*s & 128) + odd++; + else if (*s < 32 && + *s != '\n' && *s != '\r' && *s != '\b' && + *s != '\t' && *s != '\f' && *s != 27) + odd++; + } + + if ((odd * 10 > len) == (arg->arg_type == O_FTTEXT)) /* allow 10% odd */ + return &str_no; + else + return &str_yes; +} + |