summaryrefslogtreecommitdiff
path: root/util.c
diff options
context:
space:
mode:
authorLarry Wall <larry@wall.org>1988-06-05 00:00:00 +0000
committerLarry Wall <larry@wall.org>1988-06-05 00:00:00 +0000
commit378cc40b38293ffc7298c6a7ed3cd740ad79be52 (patch)
tree87bedf9adc5c88847a2e2d85963df5f94435aaf5 /util.c
parenta4de7c03d0bdc29d9d3a18abad4ac2628182ed7b (diff)
downloadperl-378cc40b38293ffc7298c6a7ed3cd740ad79be52.tar.gz
perl 2.0 (no announcement message available)perl-2.0
Some of the enhancements from Perl1 included: * New regexp routines derived from Henry Spencer's. o Support for /(foo|bar)/. o Support for /(foo)*/ and /(foo)+/. o \s for whitespace, \S for non-, \d for digit, \D nondigit * Local variables in blocks, subroutines and evals. * Recursive subroutine calls are now supported. * Array values may now be interpolated into lists: unlink 'foo', 'bar', @trashcan, 'tmp'; * File globbing. * Use of <> in array contexts returns the whole file or glob list. * New iterator for normal arrays, foreach, that allows both read and write. * Ability to open pipe to a forked off script for secure pipes in setuid scripts. * File inclusion via do 'foo.pl'; * More file tests, including -t to see if, for instance, stdin is a terminal. File tests now behave in a more correct manner. You can do file tests on filehandles as well as filenames. The special filetests -T and -B test a file to see if it's text or binary. * An eof can now be used on each file of the <> input for such purposes as resetting the line numbers or appending to each file of an inplace edit. * Assignments can now function as lvalues, so you can say things like ($HOST = $host) =~ tr/a-z/A-Z/; ($obj = $src) =~ s/\.c$/.o/; * You can now do certain file operations with a variable which holds the name of a filehandle, e.g. open(++$incl,$includefilename); $foo = <$incl>; * Warnings are now available (with -w) on use of uninitialized variables and on identifiers that are mentioned only once, and on reference to various undefined things. * There is now a wait operator. * There is now a sort operator. * The manual is now not lying when it says that perl is generally faster than sed. I hope.
Diffstat (limited to 'util.c')
-rw-r--r--util.c362
1 files changed, 335 insertions, 27 deletions
diff --git a/util.c b/util.c
index 3572c4279c..2d8a3a7cbd 100644
--- a/util.c
+++ b/util.c
@@ -1,31 +1,23 @@
-/* $Header: util.c,v 1.0.1.1 88/01/28 11:06:35 root Exp $
+/* $Header: util.c,v 2.0 88/06/05 00:15:11 root Exp $
*
* $Log: util.c,v $
- * Revision 1.0.1.1 88/01/28 11:06:35 root
- * patch8: changed fatal() to support eval operator with exiting.
- *
- * Revision 1.0 87/12/18 13:06:30 root
- * Initial revision
+ * Revision 2.0 88/06/05 00:15:11 root
+ * Baseline version 2.0.
*
*/
-#include <stdio.h>
-
-#include "handy.h"
#include "EXTERN.h"
-#include "search.h"
#include "perl.h"
-#include "INTERN.h"
-#include "util.h"
#define FLUSH
-#define MEM_SIZE unsigned int
static char nomem[] = "Out of memory!\n";
/* paranoid version of malloc */
+#ifdef DEBUGGING
static int an = 0;
+#endif
char *
safemalloc(size)
@@ -58,6 +50,8 @@ MEM_SIZE size;
char *ptr;
char *realloc();
+ if (!where)
+ fatal("Null realloc");
ptr = realloc(where,size?size:1); /* realloc(0) is NASTY on our system */
#ifdef DEBUGGING
if (debug & 128) {
@@ -83,9 +77,12 @@ char *where;
if (debug & 128)
fprintf(stderr,"0x%x: (%05d) free\n",where,an++);
#endif
- free(where);
+ if (where) {
+ free(where);
+ }
}
+#ifdef NOTDEF
/* safe version of string copy */
char *
@@ -101,6 +98,7 @@ register int len;
*dest = '\0';
return to;
}
+#endif /*NOTDEF*/
#ifdef undef
/* safe version of string concatenate, with \n deletion and space padding */
@@ -140,8 +138,12 @@ register char *to, *from;
register int delim;
{
for (; *from; from++,to++) {
- if (*from == '\\' && from[1] == delim)
- from++;
+ if (*from == '\\') {
+ if (from[1] == delim)
+ from++;
+ else if (from[1] == '\\')
+ *to++ = *from++;
+ }
else if (*from == delim)
break;
*to = *from;
@@ -151,24 +153,250 @@ register int delim;
}
/* return ptr to little string in big string, NULL if not found */
+/* This routine was donated by Corey Satten. */
char *
instr(big, little)
-char *big, *little;
+register char *big;
+register char *little;
+{
+ register char *s, *x;
+ register int first = *little++;
+
+ if (!first)
+ return big;
+ while (*big) {
+ if (*big++ != first)
+ continue;
+ for (x=big,s=little; *s; /**/ ) {
+ if (!*x)
+ return Nullch;
+ if (*s++ != *x++) {
+ s--;
+ break;
+ }
+ }
+ if (!*s)
+ return big-1;
+ }
+ return Nullch;
+}
+#ifdef NOTDEF
+void
+bmcompile(str)
+STR *str;
{
- register char *t, *s, *x;
+ register char *s;
+ register char *table;
+ register int i;
+ register int len = str->str_cur;
+
+ str_grow(str,len+128);
+ s = str->str_ptr;
+ table = s + len;
+ for (i = 1; i < 128; i++) {
+ table[i] = len;
+ }
+ i = 0;
+ while (*s) {
+ if (!isascii(*s))
+ return;
+ if (table[*s] == len)
+ table[*s] = i;
+ s++,i++;
+ }
+ str->str_pok |= 2; /* deep magic */
+}
+#endif /* NOTDEF */
+
+static unsigned char freq[] = {
+ 1, 2, 84, 151, 154, 155, 156, 157,
+ 165, 246, 250, 3, 158, 7, 18, 29,
+ 40, 51, 62, 73, 85, 96, 107, 118,
+ 129, 140, 147, 148, 149, 150, 152, 153,
+ 255, 182, 224, 205, 174, 176, 180, 217,
+ 233, 232, 236, 187, 235, 228, 234, 226,
+ 222, 219, 211, 195, 188, 193, 185, 184,
+ 191, 183, 201, 229, 181, 220, 194, 162,
+ 163, 208, 186, 202, 200, 218, 198, 179,
+ 178, 214, 166, 170, 207, 199, 209, 206,
+ 204, 160, 212, 216, 215, 192, 175, 173,
+ 243, 172, 161, 190, 203, 189, 164, 230,
+ 167, 248, 227, 244, 242, 255, 241, 231,
+ 240, 253, 169, 210, 245, 237, 249, 247,
+ 239, 168, 252, 251, 254, 238, 223, 221,
+ 213, 225, 177, 197, 171, 196, 159, 4,
+ 5, 6, 8, 9, 10, 11, 12, 13,
+ 14, 15, 16, 17, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39,
+ 41, 42, 43, 44, 45, 46, 47, 48,
+ 49, 50, 52, 53, 54, 55, 56, 57,
+ 58, 59, 60, 61, 63, 64, 65, 66,
+ 67, 68, 69, 70, 71, 72, 74, 75,
+ 76, 77, 78, 79, 80, 81, 82, 83,
+ 86, 87, 88, 89, 90, 91, 92, 93,
+ 94, 95, 97, 98, 99, 100, 101, 102,
+ 103, 104, 105, 106, 108, 109, 110, 111,
+ 112, 113, 114, 115, 116, 117, 119, 120,
+ 121, 122, 123, 124, 125, 126, 127, 128,
+ 130, 131, 132, 133, 134, 135, 136, 137,
+ 138, 139, 141, 142, 143, 144, 145, 146
+};
- for (t = big; *t; t++) {
- for (x=t,s=little; *s; x++,s++) {
+void
+fbmcompile(str)
+STR *str;
+{
+ register char *s;
+ register char *table;
+ register int i;
+ register int len = str->str_cur;
+ int rarest = 0;
+ int frequency = 256;
+
+ str_grow(str,len+128);
+ table = str->str_ptr + len; /* actually points at final '\0' */
+ s = table - 1;
+ for (i = 1; i < 128; i++) {
+ table[i] = len;
+ }
+ i = 0;
+ while (s >= str->str_ptr) {
+ if (!isascii(*s))
+ return;
+ if (table[*s] == len)
+ table[*s] = i;
+ s--,i++;
+ }
+ str->str_pok |= 2; /* deep magic */
+
+ s = str->str_ptr; /* deeper magic */
+ for (i = 0; i < len; i++) {
+ if (freq[s[i]] < frequency) {
+ rarest = i;
+ frequency = freq[s[i]];
+ }
+ }
+ str->str_rare = s[rarest];
+ str->str_prev = rarest;
+#ifdef DEBUGGING
+ if (debug & 512)
+ fprintf(stderr,"rarest char %c at %d\n",str->str_rare, str->str_prev);
+#endif
+}
+
+#ifdef NOTDEF
+char *
+bminstr(big, biglen, littlestr)
+register char *big;
+int biglen;
+STR *littlestr;
+{
+ register char *s;
+ register int tmp;
+ register char *little = littlestr->str_ptr;
+ int littlelen = littlestr->str_cur;
+ register char *table = little + littlelen;
+
+ s = big + biglen - littlelen;
+ while (s >= big) {
+ if (tmp = table[*s]) {
+ s -= tmp;
+ }
+ else {
+ if (strnEQ(s,little,littlelen))
+ return s;
+ s--;
+ }
+ }
+ return Nullch;
+}
+#endif /* NOTDEF */
+
+char *
+fbminstr(big, bigend, littlestr)
+char *big;
+register char *bigend;
+STR *littlestr;
+{
+ register char *s;
+ register int tmp;
+ register int littlelen;
+ register char *little;
+ register char *table;
+ register char *olds;
+ register char *oldlittle;
+ register int min;
+ char *screaminstr();
+
+ if (littlestr->str_pok != 3)
+ return instr(big,littlestr->str_ptr);
+
+ littlelen = littlestr->str_cur;
+ table = littlestr->str_ptr + littlelen;
+ s = big + --littlelen;
+ oldlittle = little = table - 1;
+ while (s < bigend) {
+ top:
+ if (tmp = table[*s]) {
+ s += tmp;
+ }
+ else {
+ tmp = littlelen; /* less expensive than calling strncmp() */
+ olds = s;
+ while (tmp--) {
+ if (*--s == *--little)
+ continue;
+ s = olds + 1; /* here we pay the price for failure */
+ little = oldlittle;
+ if (s < bigend) /* fake up continue to outer loop */
+ goto top;
+ return Nullch;
+ }
+ return s;
+ }
+ }
+ return Nullch;
+}
+
+char *
+screaminstr(bigstr, littlestr)
+STR *bigstr;
+STR *littlestr;
+{
+ register char *s, *x;
+ register char *big = bigstr->str_ptr;
+ register int pos;
+ register int previous;
+ register int first;
+ register char *little;
+
+ if ((pos = screamfirst[littlestr->str_rare]) < 0)
+ return Nullch;
+ little = littlestr->str_ptr;
+ first = *little++;
+ previous = littlestr->str_prev;
+ big -= previous;
+ while (pos < previous) {
+ if (!(pos += screamnext[pos]))
+ return Nullch;
+ }
+ do {
+ if (big[pos] != first)
+ continue;
+ for (x=big+pos+1,s=little; *s; /**/ ) {
if (!*x)
return Nullch;
- if (*s != *x)
+ if (*s++ != *x++) {
+ s--;
break;
+ }
}
if (!*s)
- return t;
- }
+ return big+pos;
+ } while (pos += screamnext[pos]);
return Nullch;
}
@@ -201,6 +429,35 @@ int newlen;
}
}
+extern int errno;
+
+/*VARARGS1*/
+mess(pat,a1,a2,a3,a4)
+char *pat;
+{
+ char *s;
+
+ s = tokenbuf;
+ sprintf(s,pat,a1,a2,a3,a4);
+ s += strlen(s);
+ if (s[-1] != '\n') {
+ if (line) {
+ sprintf(s," at %s line %ld",
+ in_eval?filename:origfilename, (long)line);
+ s += strlen(s);
+ }
+ if (last_in_stab &&
+ last_in_stab->stab_io &&
+ last_in_stab->stab_io->lines ) {
+ sprintf(s,", <%s> line %ld",
+ last_in_stab == argvstab ? "" : last_in_stab->stab_name,
+ (long)last_in_stab->stab_io->lines);
+ s += strlen(s);
+ }
+ strcpy(s,".\n");
+ }
+}
+
/*VARARGS1*/
fatal(pat,a1,a2,a3,a4)
char *pat;
@@ -208,15 +465,26 @@ char *pat;
extern FILE *e_fp;
extern char *e_tmpname;
+ mess(pat,a1,a2,a3,a4);
if (in_eval) {
- sprintf(tokenbuf,pat,a1,a2,a3,a4);
str_set(stabent("@",TRUE)->stab_val,tokenbuf);
longjmp(eval_env,1);
}
- fprintf(stderr,pat,a1,a2,a3,a4);
+ fputs(tokenbuf,stderr);
+ fflush(stderr);
if (e_fp)
UNLINK(e_tmpname);
- exit(1);
+ statusvalue >>= 8;
+ exit(errno?errno:(statusvalue?statusvalue:255));
+}
+
+/*VARARGS1*/
+warn(pat,a1,a2,a3,a4)
+char *pat;
+{
+ mess(pat,a1,a2,a3,a4);
+ fputs(tokenbuf,stderr);
+ fflush(stderr);
}
static bool firstsetenv = TRUE;
@@ -251,7 +519,7 @@ char *nam, *val;
#endif /* lint */
environ[i+1] = Nullch; /* make sure it's null terminated */
}
- environ[i] = safemalloc(strlen(nam) + strlen(val) + 2);
+ environ[i] = safemalloc((MEM_SIZE)(strlen(nam) + strlen(val) + 2));
/* this may or may not be in */
/* the old environ structure */
sprintf(environ[i],"%s=%s",nam,val);/* all that work just for this */
@@ -269,3 +537,43 @@ char *nam;
} /* potential SEGV's */
return i;
}
+
+#ifdef EUNICE
+unlnk(f) /* unlink all versions of a file */
+char *f;
+{
+ int i;
+
+ for (i = 0; unlink(f) >= 0; i++) ;
+ return i ? 0 : -1;
+}
+#endif
+
+#ifndef BCOPY
+#ifndef MEMCPY
+char *
+bcopy(from,to,len)
+register char *from;
+register char *to;
+register int len;
+{
+ char *retval = to;
+
+ while (len--)
+ *to++ = *from++;
+ return retval;
+}
+
+char *
+bzero(loc,len)
+register char *loc;
+register int len;
+{
+ char *retval = loc;
+
+ while (len--)
+ *loc++ = 0;
+ return retval;
+}
+#endif
+#endif