This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
6d6f28834f05224dd659487bed52cf1559c6b768
[perl5.git] / do / fttext
1 STR *
2 do_fttext(arg,TARG)
3 register ARG *arg;
4 STR *TARG;
5 {
6     int i;
7     int len;
8     int odd = 0;
9     STDCHAR tbuf[512];
10     register STDCHAR *s;
11     register STIO *stio;
12
13     if (arg[1].arg_type & A_DONT) {
14         if (arg[1].arg_ptr.arg_stab == defstab) {
15             if (statstab)
16                 stio = stab_io(statstab);
17             else {
18                 TARG = statname;
19                 goto really_filename;
20             }
21         }
22         else {
23             statstab = arg[1].arg_ptr.arg_stab;
24             str_set(statname,"");
25             stio = stab_io(statstab);
26         }
27         if (stio && stio->ifp) {
28 #if defined(STDSTDIO) || defined(atarist) /* this will work with atariST */
29             fstat(fileno(stio->ifp),&statcache);
30             if (S_ISDIR(statcache.st_mode))     /* handle NFS glitch */
31                 return arg->arg_type == O_FTTEXT ? &str_no : &str_yes;
32             if (stio->ifp->_cnt <= 0) {
33                 i = getc(stio->ifp);
34                 if (i != EOF)
35                     (void)ungetc(i,stio->ifp);
36             }
37             if (stio->ifp->_cnt <= 0)   /* null file is anything */
38                 return &str_yes;
39             len = stio->ifp->_cnt + (stio->ifp->_ptr - stio->ifp->_base);
40             s = stio->ifp->_base;
41 #else
42             fatal("-T and -B not implemented on filehandles");
43 #endif
44         }
45         else {
46             if (dowarn)
47                 warn("Test on unopened file <%s>",
48                   stab_ename(arg[1].arg_ptr.arg_stab));
49             errno = EBADF;
50             return &str_undef;
51         }
52     }
53     else {
54         statstab = Nullstab;
55         str_set(statname,str_get(TARG));
56       really_filename:
57         i = open(str_get(TARG),0);
58         if (i < 0) {
59             if (dowarn && index(str_get(TARG), '\n'))
60                 warn(warn_nl, "open");
61             return &str_undef;
62         }
63         fstat(i,&statcache);
64         len = read(i,tbuf,512);
65         (void)close(i);
66         if (len <= 0) {
67             if (S_ISDIR(statcache.st_mode) && arg->arg_type == O_FTTEXT)
68                 return &str_no;         /* special case NFS directories */
69             return &str_yes;            /* null file is anything */
70         }
71         s = tbuf;
72     }
73
74     /* now scan s to look for textiness */
75
76     for (i = 0; i < len; i++,s++) {
77         if (!*s) {                      /* null never allowed in text */
78             odd += len;
79             break;
80         }
81         else if (*s & 128)
82             odd++;
83         else if (*s < 32 &&
84           *s != '\n' && *s != '\r' && *s != '\b' &&
85           *s != '\t' && *s != '\f' && *s != 27)
86             odd++;
87     }
88
89     if ((odd * 10 > len) == (arg->arg_type == O_FTTEXT)) /* allow 10% odd */
90         return &str_no;
91     else
92         return &str_yes;
93 }
94