perl 3.0 patch #22 patch #19, continued
[p5sagit/p5-mst-13.2.git] / util.c
diff --git a/util.c b/util.c
index 4d24d1c..07e057b 100644 (file)
--- a/util.c
+++ b/util.c
@@ -1,4 +1,4 @@
-/* $Header: util.c,v 3.0 89/10/18 15:32:43 lwall Locked $
+/* $Header: util.c,v 3.0.1.5 90/03/27 16:35:13 lwall Locked $
  *
  *    Copyright (c) 1989, Larry Wall
  *
@@ -6,6 +6,27 @@
  *    as specified in the README file that comes with the perl 3.0 kit.
  *
  * $Log:       util.c,v $
+ * Revision 3.0.1.5  90/03/27  16:35:13  lwall
+ * patch16: MSDOS support
+ * patch16: support for machines that can't cast negative floats to unsigned ints
+ * patch16: tail anchored pattern could dump if string to search was shorter
+ * 
+ * Revision 3.0.1.4  90/03/01  10:26:48  lwall
+ * patch9: fbminstr() called instr() rather than ninstr()
+ * patch9: nested evals clobbered their longjmp environment
+ * patch9: piped opens returned undefined rather than 0 in child
+ * patch9: the x operator is now up to 10 times faster
+ * 
+ * Revision 3.0.1.3  89/12/21  20:27:41  lwall
+ * patch7: errno may now be a macro with an lvalue
+ * 
+ * Revision 3.0.1.2  89/11/17  15:46:35  lwall
+ * patch5: BZERO separate from BCOPY now
+ * patch5: byteorder now is a hex value
+ * 
+ * Revision 3.0.1.1  89/11/11  05:06:13  lwall
+ * patch2: made dup2 a little better
+ * 
  * Revision 3.0  89/10/18  15:32:43  lwall
  * 3.0 baseline
  * 
@@ -13,7 +34,6 @@
 
 #include "EXTERN.h"
 #include "perl.h"
-#include "errno.h"
 #include <signal.h>
 
 #ifdef I_VFORK
@@ -470,12 +490,15 @@ STR *littlestr;
 
 #ifndef lint
     if (!(littlestr->str_pok & SP_FBM))
-       return instr((char*)big,littlestr->str_ptr);
+       return ninstr((char*)big,(char*)bigend,
+               littlestr->str_ptr, littlestr->str_ptr + littlestr->str_cur);
 #endif
 
     littlelen = littlestr->str_cur;
 #ifndef lint
     if (littlestr->str_pok & SP_TAIL && !multiline) {  /* tail anchored? */
+       if (littlelen > bigend - big)
+           return Nullch;
        little = (unsigned char*)littlestr->str_ptr;
        if (littlestr->str_pok & SP_CASEFOLD) { /* oops, fake it */
            big = bigend - littlelen;           /* just start near end */
@@ -688,8 +711,6 @@ int newlen;
     }
 }
 
-extern int errno;
-
 #ifndef VARARGS
 /*VARARGS1*/
 mess(pat,a1,a2,a3,a4)
@@ -726,11 +747,33 @@ long a1, a2, a3, a4;
 {
     extern FILE *e_fp;
     extern char *e_tmpname;
+    char *tmps;
 
     mess(pat,a1,a2,a3,a4);
     if (in_eval) {
        str_set(stab_val(stabent("@",TRUE)),buf);
-       longjmp(eval_env,1);
+       tmps = "_EVAL_";
+       while (loop_ptr >= 0 && (!loop_stack[loop_ptr].loop_label ||
+         strNE(tmps,loop_stack[loop_ptr].loop_label) )) {
+#ifdef DEBUGGING
+           if (debug & 4) {
+               deb("(Skipping label #%d %s)\n",loop_ptr,
+                   loop_stack[loop_ptr].loop_label);
+           }
+#endif
+           loop_ptr--;
+       }
+#ifdef DEBUGGING
+       if (debug & 4) {
+           deb("(Found label #%d %s)\n",loop_ptr,
+               loop_stack[loop_ptr].loop_label);
+       }
+#endif
+       if (loop_ptr < 0) {
+           in_eval = 0;
+           fatal("Bad label: %s", tmps);
+       }
+       longjmp(loop_stack[loop_ptr].loop_env, 1);
     }
     fputs(buf,stderr);
     (void)fflush(stderr);
@@ -802,6 +845,7 @@ va_dcl
     va_list args;
     extern FILE *e_fp;
     extern char *e_tmpname;
+    char *tmps;
 
 #ifndef lint
     va_start(args);
@@ -812,7 +856,28 @@ va_dcl
     va_end(args);
     if (in_eval) {
        str_set(stab_val(stabent("@",TRUE)),buf);
-       longjmp(eval_env,1);
+       tmps = "_EVAL_";
+       while (loop_ptr >= 0 && (!loop_stack[loop_ptr].loop_label ||
+         strNE(tmps,loop_stack[loop_ptr].loop_label) )) {
+#ifdef DEBUGGING
+           if (debug & 4) {
+               deb("(Skipping label #%d %s)\n",loop_ptr,
+                   loop_stack[loop_ptr].loop_label);
+           }
+#endif
+           loop_ptr--;
+       }
+#ifdef DEBUGGING
+       if (debug & 4) {
+           deb("(Found label #%d %s)\n",loop_ptr,
+               loop_stack[loop_ptr].loop_label);
+       }
+#endif
+       if (loop_ptr < 0) {
+           in_eval = 0;
+           fatal("Bad label: %s", tmps);
+       }
+       longjmp(loop_stack[loop_ptr].loop_env, 1);
     }
     fputs(buf,stderr);
     (void)fflush(stderr);
@@ -908,8 +973,8 @@ char *f;
 }
 #endif
 
-#ifndef BCOPY
 #ifndef MEMCPY
+#ifndef BCOPY
 char *
 bcopy(from,to,len)
 register char *from;
@@ -922,7 +987,9 @@ register int len;
        *to++ = *from++;
     return retval;
 }
+#endif
 
+#ifndef BZERO
 char *
 bzero(loc,len)
 register char *loc;
@@ -976,7 +1043,7 @@ char *pat, *args;
 #endif /* VARARGS */
 
 #ifdef MYSWAP
-#if BYTEORDER != 04321
+#if BYTEORDER != 0x4321
 short
 my_swap(s)
 short s;
@@ -997,24 +1064,24 @@ register long l;
 {
     union {
        long result;
-       char c[4];
+       char c[sizeof(long)];
     } u;
 
-#if BYTEORDER == 01234
+#if BYTEORDER == 0x1234
     u.c[0] = (l >> 24) & 255;
     u.c[1] = (l >> 16) & 255;
     u.c[2] = (l >> 8) & 255;
     u.c[3] = l & 255;
     return u.result;
 #else
-#if ((BYTEORDER - 01111) & 0444) || !(BYTEORDER & 7)
+#if ((BYTEORDER - 0x1111) & 0x444) || !(BYTEORDER & 0xf)
     fatal("Unknown BYTEORDER\n");
 #else
     register int o;
     register int s;
 
-    for (o = BYTEORDER - 01111, s = 0; s < 32; o >>= 3, s += 8) {
-       u.c[o & 7] = (l >> s) & 255;
+    for (o = BYTEORDER - 0x1111, s = 0; s < (sizeof(long)*8); o >>= 4, s += 8) {
+       u.c[o & 0xf] = (l >> s) & 255;
     }
     return u.result;
 #endif
@@ -1027,17 +1094,17 @@ register long l;
 {
     union {
        long l;
-       char c[4];
+       char c[sizeof(long)];
     } u;
 
-#if BYTEORDER == 01234
+#if BYTEORDER == 0x1234
     u.c[0] = (l >> 24) & 255;
     u.c[1] = (l >> 16) & 255;
     u.c[2] = (l >> 8) & 255;
     u.c[3] = l & 255;
     return u.l;
 #else
-#if ((BYTEORDER - 01111) & 0444) || !(BYTEORDER & 7)
+#if ((BYTEORDER - 0x1111) & 0x444) || !(BYTEORDER & 0xf)
     fatal("Unknown BYTEORDER\n");
 #else
     register int o;
@@ -1045,17 +1112,18 @@ register long l;
 
     u.l = l;
     l = 0;
-    for (o = BYTEORDER - 01111, s = 0; s < 32; o >>= 3, s += 8) {
-       l |= (u.c[o & 7] & 255) << s;
+    for (o = BYTEORDER - 0x1111, s = 0; s < (sizeof(long)*8); o >>= 4, s += 8) {
+       l |= (u.c[o & 0xf] & 255) << s;
     }
     return l;
 #endif
 #endif
 }
 
-#endif /* BYTEORDER != 04321 */
+#endif /* BYTEORDER != 0x4321 */
 #endif /* HTONS */
 
+#ifndef MSDOS
 FILE *
 mypopen(cmd,mode)
 char   *cmd;
@@ -1089,11 +1157,21 @@ char    *mode;
            close(p[THIS]);
        }
        if (doexec) {
+#if !defined(FCNTL) || !defined(F_SETFD)
+           int fd;
+
+#ifndef NOFILE
+#define NOFILE 20
+#endif
+           for (fd = 3; fd < NOFILE; fd++)
+               close(fd);
+#endif
            do_exec(cmd);       /* may or may not use the shell */
            _exit(1);
        }
        if (tmpstab = stabent("$",allstabs))
            str_numset(STAB_STR(tmpstab),(double)getpid());
+       forkprocess = 0;
        return Nullfp;
 #undef THIS
 #undef THAT
@@ -1105,17 +1183,42 @@ char    *mode;
     forkprocess = pid;
     return fdopen(p[this], mode);
 }
+#endif /* !MSDOS */
+
+#ifdef NOTDEF
+dumpfds(s)
+char *s;
+{
+    int fd;
+    struct stat tmpstatbuf;
+
+    fprintf(stderr,"%s", s);
+    for (fd = 0; fd < 32; fd++) {
+       if (fstat(fd,&tmpstatbuf) >= 0)
+           fprintf(stderr," %d",fd);
+    }
+    fprintf(stderr,"\n");
+}
+#endif
 
 #ifndef DUP2
 dup2(oldfd,newfd)
 int oldfd;
 int newfd;
 {
+    int fdtmp[10];
+    int fdx = 0;
+    int fd;
+
     close(newfd);
-    while (dup(oldfd) != newfd) ;      /* good enough for our purposes */
+    while ((fd = dup(oldfd)) != newfd) /* good enough for low fd's */
+       fdtmp[fdx++] = fd;
+    while (fdx > 0)
+       close(fdtmp[--fdx]);
 }
 #endif
 
+#ifndef MSDOS
 int
 mypclose(ptr)
 FILE *ptr;
@@ -1157,6 +1260,7 @@ FILE *ptr;
     str_numset(str,0.0);
     return(status);
 }
+#endif /* !MSDOS */
 
 pidgone(pid,status)
 int pid;
@@ -1194,3 +1298,41 @@ register int len;
     return 0;
 }
 #endif /* MEMCMP */
+
+void
+repeatcpy(to,from,len,count)
+register char *to;
+register char *from;
+int len;
+register int count;
+{
+    register int todo;
+    register char *frombase = from;
+
+    if (len == 1) {
+       todo = *from;
+       while (count-- > 0)
+           *to++ = todo;
+       return;
+    }
+    while (count-- > 0) {
+       for (todo = len; todo > 0; todo--) {
+           *to++ = *from++;
+       }
+       from = frombase;
+    }
+}
+
+#ifndef CASTNEGFLOAT
+unsigned long
+castulong(f)
+double f;
+{
+    long along;
+
+    if (f >= 0.0)
+       return (unsigned long)f;
+    along = (long)f;
+    return (unsigned long)along;
+}
+#endif