diff options
author | Larry Wall <larry@wall.org> | 1988-06-05 00:00:00 +0000 |
---|---|---|
committer | Larry Wall <larry@wall.org> | 1988-06-05 00:00:00 +0000 |
commit | 378cc40b38293ffc7298c6a7ed3cd740ad79be52 (patch) | |
tree | 87bedf9adc5c88847a2e2d85963df5f94435aaf5 /util.c | |
parent | a4de7c03d0bdc29d9d3a18abad4ac2628182ed7b (diff) | |
download | perl-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.c | 362 |
1 files changed, 335 insertions, 27 deletions
@@ -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 |