/programs/develop/libraries/menuetlibc/src/libc/posix/Makefile |
---|
0,0 → 1,47 |
all: |
make -C dirent |
make -C fcntl |
make -C fnmatch |
make -C glob |
make -C grp |
make -C pwd |
make -C regex |
make -C setjmp |
make -C signal |
make -C stdio |
make -C sys |
make -C unistd |
make -C utime |
make -C utsname |
clean: |
make -C dirent clean |
make -C fcntl clean |
make -C fnmatch clean |
make -C glob clean |
make -C grp clean |
make -C pwd clean |
make -C regex clean |
make -C setjmp clean |
make -C signal clean |
make -C stdio clean |
make -C sys clean |
make -C unistd clean |
make -C utime clean |
make -C utsname clean |
depend: |
make -C dirent depend |
make -C fcntl depend |
make -C fnmatch depend |
make -C glob depend |
make -C grp depend |
make -C pwd depend |
make -C regex depend |
make -C setjmp depend |
make -C signal depend |
make -C stdio depend |
make -C sys depend |
make -C unistd depend |
make -C utime depend |
make -C utsname depend |
/programs/develop/libraries/menuetlibc/src/libc/posix/dirent/Makefile |
---|
0,0 → 1,4 |
THIS_SRCS = closedir.c odflags.c opendir.c readdir.c rewinddi.c seekdir.c \ |
telldir.c |
include $(MENUET_LIBC_TOPDIR)/Make.rules |
/programs/develop/libraries/menuetlibc/src/libc/posix/dirent/closedir.c |
---|
0,0 → 1,11 |
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ |
#include <stdlib.h> |
#include <dirent.h> |
#include "dirstruc.h" |
int |
closedir(DIR *dir) |
{ |
free(dir); |
return 0; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/dirent/dirstruc.h |
---|
0,0 → 1,10 |
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ |
#include <dir.h> |
struct __dj_DIR { |
int num_read; |
char *name; |
int flags; |
struct ffblk ff; |
struct dirent de; |
}; |
/programs/develop/libraries/menuetlibc/src/libc/posix/dirent/odflags.c |
---|
0,0 → 1,4 |
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ |
#include <dirent.h> |
int __opendir_flags = 0; |
/programs/develop/libraries/menuetlibc/src/libc/posix/dirent/opendir.c |
---|
0,0 → 1,43 |
/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */ |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <libc/stubs.h> |
#include <stdlib.h> |
#include <string.h> |
#include <dirent.h> |
#include <errno.h> |
#include <limits.h> |
#include <unistd.h> |
#include <sys/stat.h> |
#include "dirstruc.h" |
DIR * |
opendir(const char *name) |
{ |
int res; |
DIR* dir = (DIR*)malloc(sizeof(DIR)); |
if (!dir) |
return NULL; |
_fixpath(name, dir->fileinfo.name); |
struct bdfe_item attr; |
dir->fileinfo.command = 5; |
dir->fileinfo.file_offset_low = 0; |
dir->fileinfo.file_offset_high = 0; |
dir->fileinfo.size = 0; |
dir->fileinfo.data_pointer = (__u32)&attr; |
res = __kolibri__system_tree_access2(&dir->fileinfo); |
if (res!=0 && res!=2) |
{ |
free(dir); |
return NULL; |
} |
if (res==0 && (attr.attr & 0x10)==0) |
{ |
free(dir); |
return NULL; |
} |
dir->fileinfo.command = 1; |
dir->fileinfo.size = 1; |
dir->fileinfo.data_pointer = (__u32)dir->bdfeheader; |
dir->fileinfo.file_offset_low = (__u32)-1; |
return dir; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/dirent/readdir.c |
---|
0,0 → 1,18 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <libc/stubs.h> |
#include <string.h> |
#include <dirent.h> |
#include <errno.h> |
#include <ctype.h> |
#include "dirstruc.h" |
struct dirent * |
readdir(DIR *dir) |
{ |
dir->fileinfo.file_offset_low++; |
if (__kolibri__system_tree_access2(&dir->fileinfo)) |
return NULL; |
dir->entry.d_namlen = strlen(dir->bdfename); |
strcpy(dir->entry.d_name, dir->bdfename); |
return &dir->entry; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/dirent/rewinddi.c |
---|
0,0 → 1,9 |
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ |
#include <dirent.h> |
#include "dirstruc.h" |
void |
rewinddir(DIR *dir) |
{ |
// dir->num_read = 0; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/dirent/seekdir.c |
---|
0,0 → 1,11 |
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ |
#include <dirent.h> |
void |
seekdir(DIR *dir, long loc) |
{ |
/* int i; |
rewinddir(dir); |
for (i=0; i<loc; i++) |
readdir(dir);*/ |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/dirent/telldir.c |
---|
0,0 → 1,9 |
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ |
#include <dirent.h> |
#include "dirstruc.h" |
long |
telldir(DIR *dir) |
{ |
// return dir->num_read; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/fcntl/Makefile |
---|
0,0 → 1,3 |
THIS_SRCS = creat.c fcntl.c open.c |
include $(MENUET_LIBC_TOPDIR)/Make.rules |
/programs/develop/libraries/menuetlibc/src/libc/posix/fcntl/creat.c |
---|
0,0 → 1,7 |
#include <fcntl.h> |
int |
creat(const char *path, mode_t mode) |
{ |
return open(path, O_WRONLY|O_CREAT|O_TRUNC, mode); |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/fcntl/fcntl.c |
---|
0,0 → 1,22 |
#include <unistd.h> |
#include <fcntl.h> |
int |
fcntl(int fd, int cmd, ...) |
{ |
switch (cmd) |
{ |
case F_DUPFD: |
return dup(fd); |
case F_GETFD: |
case F_SETFD: |
case F_GETFL: |
case F_SETFL: |
return 0; |
case F_GETLK: |
case F_SETLK: |
case F_SETLKW: |
return -1; |
} |
return -1; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/fcntl/open.c |
---|
0,0 → 1,31 |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include <errno.h> |
#include <fcntl.h> |
#include <unistd.h> |
#include <sys/stat.h> |
#include <io.h> |
#include <libc/dosio.h> |
int open(const char* filename, int oflag, ...) |
{ |
/* int fd, dmode, bintext; |
bintext = oflag & (O_TEXT | O_BINARY); |
if (!bintext) bintext = _fmode & (O_TEXT | O_BINARY); |
if (!bintext) bintext = O_BINARY; |
oflag &= ~(O_TEXT | O_BINARY); |
dmode = (*((&oflag)+1) & S_IWUSR) ? 1 : 0; |
fd = _open(filename, oflag & 0xff); |
if (fd == -1 && oflag & O_CREAT) |
fd = _creat(filename, dmode); |
if (fd == -1) return fd; |
if (oflag & O_TRUNC) |
if (_write(fd, 0, 0) < 0) |
return -1; |
if(oflag & O_APPEND) |
lseek(fd, 0, SEEK_END); |
return fd;*/ |
return dosemu_open(filename, oflag); |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/fnmatch/Makefile |
---|
0,0 → 1,3 |
THIS_SRCS = fnmatch.c |
include $(MENUET_LIBC_TOPDIR)/Make.rules |
/programs/develop/libraries/menuetlibc/src/libc/posix/fnmatch/fnmatch.c |
---|
0,0 → 1,143 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <libc/stubs.h> |
#include <unistd.h> |
#include <string.h> |
#include <ctype.h> |
#include <fnmatch.h> |
#define EOS '\0' |
static const char *rangematch(const char *pattern, char test, int nocase); |
#define isslash(c) ((c) == '\\' || (c) == '/') |
static const char * |
find_slash(const char *s) |
{ |
while (*s) |
{ |
if (isslash(*s)) |
return s; |
s++; |
} |
return 0; |
} |
static const char * |
rangematch(const char *pattern, char test, int nocase) |
{ |
char c, c2; |
int negate, ok; |
if ((negate = (*pattern == '!'))) |
++pattern; |
for (ok = 0; (c = *pattern++) != ']';) |
{ |
if (c == 0) |
return 0; /* illegal pattern */ |
if (*pattern == '-' && (c2 = pattern[1]) != 0 && c2 != ']') |
{ |
if (c <= test && test <= c2) |
ok = 1; |
if (nocase && toupper(c) <= toupper(test) && toupper(test) <= toupper(c2)) |
ok = 1; |
pattern += 2; |
} |
else if (c == test) |
ok = 1; |
else if (nocase && (toupper(c) == toupper(test))) |
ok = 1; |
} |
return ok == negate ? NULL : pattern; |
} |
int |
fnmatch(const char *pattern, const char *string, int flags) |
{ |
char c; |
char test; |
for (;;) |
switch ((c = *pattern++)) |
{ |
case 0: |
return *string == 0 ? 0 : FNM_NOMATCH; |
case '?': |
if ((test = *string++) == 0 || |
(isslash(test) && (flags & FNM_PATHNAME))) |
return(FNM_NOMATCH); |
break; |
case '*': |
c = *pattern; |
/* collapse multiple stars */ |
while (c == '*') |
c = *++pattern; |
/* optimize for pattern with * at end or before / */ |
if (c == 0) |
if (flags & FNM_PATHNAME) |
return find_slash(string) ? FNM_NOMATCH : 0; |
else |
return 0; |
else if (isslash(c) && flags & FNM_PATHNAME) |
{ |
if ((string = find_slash(string)) == NULL) |
return FNM_NOMATCH; |
break; |
} |
/* general case, use recursion */ |
while ((test = *string) != 0) |
{ |
if (fnmatch(pattern, string, flags) == 0) |
return(0); |
if (isslash(test) && flags & FNM_PATHNAME) |
break; |
++string; |
} |
return FNM_NOMATCH; |
case '[': |
if ((test = *string++) == 0 || |
(isslash(test) && flags & FNM_PATHNAME)) |
return FNM_NOMATCH; |
if ((pattern = rangematch(pattern, test, flags & FNM_NOCASE)) == NULL) |
return FNM_NOMATCH; |
break; |
case '\\': |
if (!(flags & FNM_NOESCAPE) && pattern[1] && strchr("*?[\\", pattern[1])) |
{ |
if ((c = *pattern++) == 0) |
{ |
c = '\\'; |
--pattern; |
} |
if (c != *string++) |
return FNM_NOMATCH; |
break; |
} |
/* FALLTHROUGH */ |
default: |
if (isslash(c) && isslash(*string)) |
{ |
string++; |
break; |
} |
if (flags & FNM_NOCASE) |
{ |
if (toupper(c) != toupper(*string++)) |
return FNM_NOMATCH; |
} |
else |
{ |
if (c != *string++) |
return FNM_NOMATCH; |
} |
break; |
} |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/glob/Makefile |
---|
0,0 → 1,3 |
THIS_SRCS = glob.c globfree.c |
include $(MENUET_LIBC_TOPDIR)/Make.rules |
/programs/develop/libraries/menuetlibc/src/libc/posix/glob/glob.c |
---|
0,0 → 1,341 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <libc/stubs.h> |
#include <stdio.h> |
#include <string.h> |
#include <stdlib.h> |
#include <ctype.h> |
#include <unistd.h> |
#include <fnmatch.h> |
#include <dir.h> |
#include <glob.h> |
typedef struct Save { |
struct Save *prev; |
char *entry; |
} Save; |
static Save *save_list; |
static int save_count; |
static int flags; |
static int (*errfunc)(const char *epath, int eerno); |
static char *pathbuf; |
static int wildcard_nesting; |
static char use_lower_case; |
static char slash; |
static int glob2(const char *pattern, char *epathbuf); |
static int add(const char *path); |
static int str_compare(const void *va, const void *vb); |
static int |
add(const char *path) |
{ |
Save *sp; |
for (sp=save_list; sp; sp=sp->prev) |
if (strcmp(sp->entry, path) == 0) |
return 0; |
sp = (Save *)malloc(sizeof(Save)); |
if (sp == 0) |
return 1; |
sp->entry = (char *)malloc(strlen(path)+1); |
if (sp->entry == 0) |
{ |
free(sp); |
return 1; |
} |
/* printf("add: `%s'\n", path); */ |
strcpy(sp->entry, path); |
sp->prev = save_list; |
save_list = sp; |
save_count++; |
return 0; |
} |
static int |
glob_dirs(const char *rest, char *epathbuf, int first) /* rest is ptr to null or ptr after slash, bp after slash */ |
{ |
struct ffblk ff; |
int done; |
/* printf("glob_dirs[%d]: rest=`%s' %c epathbuf=`%s' %c pathbuf=`%s'\n", |
wildcard_nesting, rest, *rest, epathbuf, *epathbuf, pathbuf); */ |
if (first) |
{ |
if (*rest) |
{ |
glob2(rest, epathbuf); |
} |
else |
{ |
char sl = epathbuf[-1]; |
*epathbuf = 0; |
/* printf("end, checking `%s'\n", pathbuf); */ |
if (epathbuf == pathbuf) |
{ |
epathbuf[0] = '.'; |
epathbuf[1] = 0; |
} |
else |
epathbuf[-1] = 0; |
if (__file_exists(pathbuf)) |
add(pathbuf); |
epathbuf[-1] = sl; |
} |
} |
strcpy(epathbuf, "*.*"); |
done = findfirst(pathbuf, &ff, FA_DIREC); |
while (!done) |
{ |
if ((ff.ff_name[0] != '.') && (ff.ff_attrib & FA_DIREC)) |
{ |
int i; |
char *tp; |
if (use_lower_case) |
for (i=0; ff.ff_name[i] && i<13; i++) |
ff.ff_name[i] = tolower(ff.ff_name[i]); |
/* printf("found `%s' `%s'\n", pathbuf, ff.ff_name); */ |
strcpy(epathbuf, ff.ff_name); |
tp = epathbuf + strlen(epathbuf); |
*tp++ = slash; |
*tp = 0; |
wildcard_nesting++; |
if (*rest) |
{ |
glob2(rest, tp); |
} |
else |
{ |
if (!(flags & GLOB_MARK)) |
tp[-1] = 0; |
add(pathbuf); |
tp[-1] = slash; |
} |
*tp = 0; |
glob_dirs(rest, tp, 0); |
wildcard_nesting--; |
} |
done = findnext(&ff); |
} |
return 0; |
} |
static int |
glob2(const char *pattern, char *epathbuf) /* both point *after* the slash */ |
{ |
const char *pp, *pslash; |
char *bp; |
struct ffblk ff; |
char *my_pattern; |
int done; |
if (strcmp(pattern, "...") == 0) |
{ |
return glob_dirs(pattern+3, epathbuf, 1); |
} |
if (strncmp(pattern, "...", 3) == 0 && (pattern[3] == '\\' || pattern[3] == '/')) |
{ |
slash = pattern[3]; |
return glob_dirs(pattern+4, epathbuf, 1); |
} |
*epathbuf = 0; |
/* copy as many non-wildcard segments as possible */ |
pp = pattern; |
bp = epathbuf; |
pslash = bp-1; |
while (1) |
{ |
if (*pp == ':' || *pp == '\\' || *pp == '/') |
{ |
pslash = bp; |
if (strcmp(pp+1, "...") == 0 |
|| (strncmp(pp+1, "...", 3) == 0 && (pp[4] == '/' || pp[4] == '\\'))) |
{ |
if (*pp != ':') |
slash = *pp; |
/* printf("glob2: dots at `%s'\n", pp); */ |
*bp++ = *pp++; |
break; |
} |
} |
else if (*pp == '*' || *pp == '?' || *pp == '[') |
{ |
if (pslash > pathbuf) |
strncpy(epathbuf, pattern, pslash - pathbuf); |
pp = pattern + (pslash - epathbuf) + 1; |
bp = epathbuf + (pslash - epathbuf) + 1; |
break; |
} |
else if (*pp == 0) |
{ |
break; |
} |
else if (islower(*pp)) |
use_lower_case = 1; |
else if (isupper(*pp)) |
use_lower_case = 0; |
*bp++ = *pp++; |
} |
*bp = 0; |
if (*pp == 0) /* end of pattern? */ |
{ |
if (wildcard_nesting==0 || __file_exists(pathbuf)) |
add(pathbuf); |
return 0; |
} |
/* printf("glob2: initial segment is `%s'\n", pathbuf); */ |
if (wildcard_nesting) |
{ |
char s = bp[-1]; |
bp[-1] = 0; |
if (!__file_exists(pathbuf)) |
return 0; |
bp[-1] = s; |
} |
for (pslash = pp; *pslash && *pslash != '\\' && *pslash != '/'; pslash++) |
{ |
if (islower(*pslash)) |
use_lower_case = 1; |
else if (isupper(*pslash)) |
use_lower_case = 0; |
} |
if (*pslash) |
slash = *pslash; |
my_pattern = (char *)alloca(pslash - pp + 1); |
if (my_pattern == 0) |
return 0; |
strncpy(my_pattern, pp, pslash - pp); |
my_pattern[pslash-pp] = 0; |
/* printf("glob2: `%s' `%s'\n", pathbuf, my_pattern); */ |
if (strcmp(my_pattern, "...") == 0) |
{ |
glob_dirs(*pslash ? pslash+1 : pslash, bp, 1); |
return 0; |
} |
strcpy(bp, "*.*"); |
done = findfirst(pathbuf, &ff, FA_RDONLY|FA_SYSTEM|FA_DIREC|FA_ARCH); |
while (!done) |
{ |
int i; |
if (ff.ff_name[0] != '.') |
{ |
if (use_lower_case) |
for (i=0; ff.ff_name[i] && i<13; i++) |
ff.ff_name[i] = tolower(ff.ff_name[i]); |
if (fnmatch(my_pattern, ff.ff_name, FNM_NOESCAPE|FNM_PATHNAME|FNM_NOCASE) == 0) |
{ |
strcpy(bp, ff.ff_name); |
if (*pslash) |
{ |
char *tp = bp + strlen(bp); |
*tp++ = *pslash; |
*tp = 0; |
/* printf("nest: `%s' `%s'\n", pslash+1, pathbuf); */ |
wildcard_nesting++; |
glob2(pslash+1, tp); |
wildcard_nesting--; |
} |
else |
{ |
/* printf("ffmatch: `%s' matching `%s', add `%s'\n", |
ff.ff_name, my_pattern, pathbuf); */ |
if (ff.ff_attrib & FA_DIREC & (flags & GLOB_MARK)) |
{ |
bp[strlen(bp)] = slash; |
bp[strlen(bp)+1] = 0; |
} |
add(pathbuf); |
} |
} |
} |
done = findnext(&ff); |
} |
return 0; |
} |
static int |
str_compare(const void *va, const void *vb) |
{ |
return strcmp(*(char * const *)va, *(char * const *)vb); |
} |
int |
glob(const char *_pattern, int _flags, int (*_errfunc)(const char *_epath, int _eerrno), glob_t *_pglob) |
{ |
char path_buffer[2000]; |
int l_ofs, l_ptr; |
pathbuf = path_buffer+1; |
flags = _flags; |
errfunc = _errfunc; |
wildcard_nesting = 0; |
save_count = 0; |
save_list = 0; |
use_lower_case = 1; |
slash = '/'; |
glob2(_pattern, pathbuf); |
if (save_count == 0) |
{ |
if (flags & GLOB_NOCHECK) |
add(_pattern); |
else |
return GLOB_NOMATCH; |
} |
if (flags & GLOB_DOOFFS) |
l_ofs = _pglob->gl_offs; |
else |
l_ofs = 0; |
if (flags & GLOB_APPEND) |
{ |
_pglob->gl_pathv = (char **)realloc(_pglob->gl_pathv, (l_ofs + _pglob->gl_pathc + save_count + 1) * sizeof(char *)); |
if (_pglob->gl_pathv == 0) |
return GLOB_ERR; |
l_ptr = l_ofs + _pglob->gl_pathc; |
} |
else |
{ |
_pglob->gl_pathv = (char* *)malloc((l_ofs + save_count + 1) * sizeof(char *)); |
if (_pglob->gl_pathv == 0) |
return GLOB_ERR; |
l_ptr = l_ofs; |
if (l_ofs) |
memset(_pglob->gl_pathv, 0, l_ofs * sizeof(char *)); |
} |
l_ptr += save_count; |
_pglob->gl_pathv[l_ptr] = 0; |
while (save_list) |
{ |
Save *s = save_list; |
l_ptr --; |
_pglob->gl_pathv[l_ptr] = save_list->entry; |
save_list = save_list->prev; |
free(s); |
} |
if (!(flags & GLOB_NOSORT)) |
qsort(_pglob->gl_pathv + l_ptr, save_count, sizeof(char *), str_compare); |
_pglob->gl_pathc = l_ptr + save_count; |
return 0; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/glob/globfree.c |
---|
0,0 → 1,14 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <stdlib.h> |
#include <glob.h> |
void globfree(glob_t *_pglob) |
{ |
int i; |
if (!_pglob->gl_pathv) |
return; |
for (i=0; i<_pglob->gl_pathc; i++) |
if (_pglob->gl_pathv[i]) |
free(_pglob->gl_pathv[i]); |
free(_pglob->gl_pathv); |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/grp/Makefile |
---|
0,0 → 1,3 |
THIS_SRCS = getgrent.c getgrgid.c |
include $(MENUET_LIBC_TOPDIR)/Make.rules |
/programs/develop/libraries/menuetlibc/src/libc/posix/grp/getgrent.c |
---|
0,0 → 1,35 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <grp.h> |
#include <unistd.h> |
static int tag = 0; |
struct group * |
getgrent(void) |
{ |
if (tag == 0) |
{ |
tag = 1; |
return getgrgid(getgid()); |
} |
return 0; |
} |
/* ARGSUSED */ |
struct group * |
fgetgrent(void *f) |
{ |
return getgrent(); |
} |
void |
setgrent(void) |
{ |
tag = 0; |
} |
void |
endgrent(void) |
{ |
tag = 0; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/grp/getgrgid.c |
---|
0,0 → 1,68 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <unistd.h> |
#include <stdlib.h> |
#include <string.h> |
#include <grp.h> |
static int init = 0; |
static char *grp = 0; |
static struct group g; |
static char *mem[2]; |
static char def_name[] = "user"; |
static char def_grp[] = "dos"; |
static void |
grp_init(void) |
{ |
char *p; |
p = getenv("USER"); |
if (p == 0) |
p = getenv("LOGNAME"); |
if (p) |
{ |
mem[0] = (char *)malloc(strlen(p) + 1); |
if (mem[0] == 0) |
mem[0] = def_name; |
else |
strcpy(mem[0], p); |
} |
else |
mem[0] = def_name; |
mem[1] = 0; |
p = getenv("GROUP"); |
if (p) |
{ |
grp = (char *)malloc(strlen(p)+1); |
if (grp == 0) |
grp = def_grp; |
else |
strcpy(grp, p); |
} |
else |
grp = def_grp; |
g.gr_gid = getgid(); |
g.gr_mem = mem; |
g.gr_name = grp; |
} |
struct group * |
getgrgid(gid_t gid) |
{ |
if (gid != getgid()) |
return 0; |
if (init == 0) |
grp_init(); |
return &g; |
} |
struct group * |
getgrnam(const char *name) |
{ |
if (init == 0) |
grp_init(); |
if (strcmp(name, grp)) |
return 0; |
return &g; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/pwd/Makefile |
---|
0,0 → 1,3 |
THIS_SRCS = getpwnam.c getpwuid.c pwent.c |
include $(MENUET_LIBC_TOPDIR)/Make.rules |
/programs/develop/libraries/menuetlibc/src/libc/posix/pwd/getpwnam.c |
---|
0,0 → 1,27 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <pwd.h> |
#include <unistd.h> |
#include <stdlib.h> |
static char slash[] = "/"; |
static char shell[] = "sh"; |
struct passwd * |
getpwnam(const char *name) |
{ |
static struct passwd rv; |
rv.pw_name = getlogin(); |
if (strcmp(rv.pw_name, name) != 0) |
return 0; |
rv.pw_uid = getuid(); |
rv.pw_gid = getgid(); |
rv.pw_dir = getenv("HOME"); |
if (rv.pw_dir == 0) |
rv.pw_dir = slash; |
rv.pw_shell = getenv("SHELL"); |
if (rv.pw_shell == 0) |
rv.pw_shell = getenv("COMSPEC"); |
if (rv.pw_shell == 0) |
rv.pw_shell = shell; |
return &rv; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/pwd/getpwuid.c |
---|
0,0 → 1,27 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <pwd.h> |
#include <unistd.h> |
#include <stdlib.h> |
static char slash[] = "/"; |
static char shell[] = "sh"; |
struct passwd * |
getpwuid(uid_t uid) |
{ |
static struct passwd rv; |
rv.pw_uid = getuid(); |
if (uid != rv.pw_uid) |
return 0; |
rv.pw_name = getlogin(); |
rv.pw_gid = getgid(); |
rv.pw_dir = getenv("HOME"); |
if (rv.pw_dir == 0) |
rv.pw_dir = slash; |
rv.pw_shell = getenv("SHELL"); |
if (rv.pw_shell == 0) |
rv.pw_shell = getenv("COMSPEC"); |
if (rv.pw_shell == 0) |
rv.pw_shell = shell; |
return &rv; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/pwd/pwent.c |
---|
0,0 → 1,28 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <pwd.h> |
#include <unistd.h> |
static int count=0; |
void |
setpwent(void) |
{ |
count=0; |
} |
struct passwd * |
getpwent(void) |
{ |
if (count == 0) |
{ |
count++; |
return getpwuid(getuid()); |
} |
return 0; |
} |
void |
endpwent(void) |
{ |
count=0; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/regex/Makefile |
---|
0,0 → 1,4 |
THIS_SRCS = debug.c regcomp.c regerror.c regexec.c regfree.c \ |
split.c |
include $(MENUET_LIBC_TOPDIR)/Make.rules |
/programs/develop/libraries/menuetlibc/src/libc/posix/regex/cclass.h |
---|
0,0 → 1,32 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
/* character-class table */ |
static struct cclass { |
char *name; |
char *chars; |
char *multis; |
} cclasses[] = { |
"alnum", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\ |
0123456789", "", |
"alpha", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", |
"", |
"blank", " \t", "", |
"cntrl", "\007\b\t\n\v\f\r\1\2\3\4\5\6\16\17\20\21\22\23\24\ |
\25\26\27\30\31\32\33\34\35\36\37\177", "", |
"digit", "0123456789", "", |
"graph", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\ |
0123456789!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", |
"", |
"lower", "abcdefghijklmnopqrstuvwxyz", |
"", |
"print", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\ |
0123456789!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ ", |
"", |
"punct", "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", |
"", |
"space", "\t\n\v\f\r ", "", |
"upper", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", |
"", |
"xdigit", "0123456789ABCDEFabcdef", |
"", |
NULL, 0, "" |
}; |
/programs/develop/libraries/menuetlibc/src/libc/posix/regex/cname.h |
---|
0,0 → 1,103 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
/* character-name table */ |
static struct cname { |
char *name; |
char code; |
} cnames[] = { |
"NUL", '\0', |
"SOH", '\001', |
"STX", '\002', |
"ETX", '\003', |
"EOT", '\004', |
"ENQ", '\005', |
"ACK", '\006', |
"BEL", '\007', |
"alert", '\007', |
"BS", '\010', |
"backspace", '\b', |
"HT", '\011', |
"tab", '\t', |
"LF", '\012', |
"newline", '\n', |
"VT", '\013', |
"vertical-tab", '\v', |
"FF", '\014', |
"form-feed", '\f', |
"CR", '\015', |
"carriage-return", '\r', |
"SO", '\016', |
"SI", '\017', |
"DLE", '\020', |
"DC1", '\021', |
"DC2", '\022', |
"DC3", '\023', |
"DC4", '\024', |
"NAK", '\025', |
"SYN", '\026', |
"ETB", '\027', |
"CAN", '\030', |
"EM", '\031', |
"SUB", '\032', |
"ESC", '\033', |
"IS4", '\034', |
"FS", '\034', |
"IS3", '\035', |
"GS", '\035', |
"IS2", '\036', |
"RS", '\036', |
"IS1", '\037', |
"US", '\037', |
"space", ' ', |
"exclamation-mark", '!', |
"quotation-mark", '"', |
"number-sign", '#', |
"dollar-sign", '$', |
"percent-sign", '%', |
"ampersand", '&', |
"apostrophe", '\'', |
"left-parenthesis", '(', |
"right-parenthesis", ')', |
"asterisk", '*', |
"plus-sign", '+', |
"comma", ',', |
"hyphen", '-', |
"hyphen-minus", '-', |
"period", '.', |
"full-stop", '.', |
"slash", '/', |
"solidus", '/', |
"zero", '0', |
"one", '1', |
"two", '2', |
"three", '3', |
"four", '4', |
"five", '5', |
"six", '6', |
"seven", '7', |
"eight", '8', |
"nine", '9', |
"colon", ':', |
"semicolon", ';', |
"less-than-sign", '<', |
"equals-sign", '=', |
"greater-than-sign", '>', |
"question-mark", '?', |
"commercial-at", '@', |
"left-square-bracket", '[', |
"backslash", '\\', |
"reverse-solidus", '\\', |
"right-square-bracket", ']', |
"circumflex", '^', |
"circumflex-accent", '^', |
"underscore", '_', |
"low-line", '_', |
"grave-accent", '`', |
"left-brace", '{', |
"left-curly-bracket", '{', |
"vertical-line", '|', |
"right-brace", '}', |
"right-curly-bracket", '}', |
"tilde", '~', |
"DEL", '\177', |
NULL, 0, |
}; |
/programs/develop/libraries/menuetlibc/src/libc/posix/regex/debug.c |
---|
0,0 → 1,243 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <stdio.h> |
#include <string.h> |
#include <ctype.h> |
#include <limits.h> |
#include <stdlib.h> |
#include <sys/types.h> |
#include <regex.h> |
#include "utils.h" |
#include "regex2.h" |
#include "debug.ih" |
/* |
- regprint - print a regexp for debugging |
== void regprint(regex_t *r, FILE *d); |
*/ |
void |
regprint(r, d) |
regex_t *r; |
FILE *d; |
{ |
register struct re_guts *g = r->re_g; |
register int i; |
register int c; |
register int last; |
int nincat[NC]; |
fprintf(d, "%ld states, %d categories", (long)g->nstates, |
g->ncategories); |
fprintf(d, ", first %ld last %ld", (long)g->firststate, |
(long)g->laststate); |
if (g->iflags&USEBOL) |
fprintf(d, ", USEBOL"); |
if (g->iflags&USEEOL) |
fprintf(d, ", USEEOL"); |
if (g->iflags&BAD) |
fprintf(d, ", BAD"); |
if (g->nsub > 0) |
fprintf(d, ", nsub=%ld", (long)g->nsub); |
if (g->must != NULL) |
fprintf(d, ", must(%ld) `%*s'", (long)g->mlen, (int)g->mlen, |
g->must); |
if (g->backrefs) |
fprintf(d, ", backrefs"); |
if (g->nplus > 0) |
fprintf(d, ", nplus %ld", (long)g->nplus); |
fprintf(d, "\n"); |
s_print(g, d); |
for (i = 0; i < g->ncategories; i++) { |
nincat[i] = 0; |
for (c = CHAR_MIN; c <= CHAR_MAX; c++) |
if (g->categories[c] == i) |
nincat[i]++; |
} |
fprintf(d, "cc0#%d", nincat[0]); |
for (i = 1; i < g->ncategories; i++) |
if (nincat[i] == 1) { |
for (c = CHAR_MIN; c <= CHAR_MAX; c++) |
if (g->categories[c] == i) |
break; |
fprintf(d, ", %d=%s", i, regchar(c)); |
} |
fprintf(d, "\n"); |
for (i = 1; i < g->ncategories; i++) |
if (nincat[i] != 1) { |
fprintf(d, "cc%d\t", i); |
last = -1; |
for (c = CHAR_MIN; c <= CHAR_MAX+1; c++) /* +1 does flush */ |
if (c <= CHAR_MAX && g->categories[c] == i) { |
if (last < 0) { |
fprintf(d, "%s", regchar(c)); |
last = c; |
} |
} else { |
if (last >= 0) { |
if (last != c-1) |
fprintf(d, "-%s", |
regchar(c-1)); |
last = -1; |
} |
} |
fprintf(d, "\n"); |
} |
} |
/* |
- s_print - print the strip for debugging |
== static void s_print(register struct re_guts *g, FILE *d); |
*/ |
static void |
s_print(g, d) |
register struct re_guts *g; |
FILE *d; |
{ |
register sop *s; |
register cset *cs; |
register int i; |
register int done = 0; |
register sop opnd; |
register int col = 0; |
register int last; |
register sopno offset = 2; |
# define GAP() { if (offset % 5 == 0) { \ |
if (col > 40) { \ |
fprintf(d, "\n\t"); \ |
col = 0; \ |
} else { \ |
fprintf(d, " "); \ |
col++; \ |
} \ |
} else \ |
col++; \ |
offset++; \ |
} |
if (OP(g->strip[0]) != OEND) |
fprintf(d, "missing initial OEND!\n"); |
for (s = &g->strip[1]; !done; s++) { |
opnd = OPND(*s); |
switch (OP(*s)) { |
case OEND: |
fprintf(d, "\n"); |
done = 1; |
break; |
case OCHAR: |
if (strchr("\\|()^$.[+*?{}!<> ", (char)opnd) != NULL) |
fprintf(d, "\\%c", (char)opnd); |
else |
fprintf(d, "%s", regchar((char)opnd)); |
break; |
case OBOL: |
fprintf(d, "^"); |
break; |
case OEOL: |
fprintf(d, "$"); |
break; |
case OBOW: |
fprintf(d, "\\{"); |
break; |
case OEOW: |
fprintf(d, "\\}"); |
break; |
case OANY: |
fprintf(d, "."); |
break; |
case OANYOF: |
fprintf(d, "[(%ld)", (long)opnd); |
cs = &g->sets[opnd]; |
last = -1; |
for (i = 0; i < g->csetsize+1; i++) /* +1 flushes */ |
if (CHIN(cs, i) && i < g->csetsize) { |
if (last < 0) { |
fprintf(d, "%s", regchar(i)); |
last = i; |
} |
} else { |
if (last >= 0) { |
if (last != i-1) |
fprintf(d, "-%s", |
regchar(i-1)); |
last = -1; |
} |
} |
fprintf(d, "]"); |
break; |
case OBACK_: |
fprintf(d, "(\\<%ld>", (long)opnd); |
break; |
case O_BACK: |
fprintf(d, "<%ld>\\)", (long)opnd); |
break; |
case OPLUS_: |
fprintf(d, "(+"); |
if (OP(*(s+opnd)) != O_PLUS) |
fprintf(d, "<%ld>", (long)opnd); |
break; |
case O_PLUS: |
if (OP(*(s-opnd)) != OPLUS_) |
fprintf(d, "<%ld>", (long)opnd); |
fprintf(d, "+)"); |
break; |
case OQUEST_: |
fprintf(d, "(?"); |
if (OP(*(s+opnd)) != O_QUEST) |
fprintf(d, "<%ld>", (long)opnd); |
break; |
case O_QUEST: |
if (OP(*(s-opnd)) != OQUEST_) |
fprintf(d, "<%ld>", (long)opnd); |
fprintf(d, "?)"); |
break; |
case OLPAREN: |
fprintf(d, "((<%ld>", (long)opnd); |
break; |
case ORPAREN: |
fprintf(d, "<%ld>))", (long)opnd); |
break; |
case OCH_: |
fprintf(d, "<"); |
if (OP(*(s+opnd)) != OOR2) |
fprintf(d, "<%ld>", (long)opnd); |
break; |
case OOR1: |
if (OP(*(s-opnd)) != OOR1 && OP(*(s-opnd)) != OCH_) |
fprintf(d, "<%ld>", (long)opnd); |
fprintf(d, "|"); |
break; |
case OOR2: |
fprintf(d, "|"); |
if (OP(*(s+opnd)) != OOR2 && OP(*(s+opnd)) != O_CH) |
fprintf(d, "<%ld>", (long)opnd); |
break; |
case O_CH: |
if (OP(*(s-opnd)) != OOR1) |
fprintf(d, "<%ld>", (long)opnd); |
fprintf(d, ">"); |
break; |
default: |
fprintf(d, "!%d(%d)!", OP(*s), opnd); |
break; |
} |
if (!done) |
GAP(); |
} |
} |
/* |
- regchar - make a character printable |
== static char *regchar(int ch); |
*/ |
static char * /* -> representation */ |
regchar(ch) |
int ch; |
{ |
static char buf[10]; |
if (isprint(ch) || ch == ' ') |
sprintf(buf, "%c", ch); |
else |
sprintf(buf, "\\%o", ch); |
return(buf); |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/regex/debug.ih |
---|
0,0 → 1,14 |
/* ========= begin header generated by ./mkh ========= */ |
#ifdef __cplusplus |
extern "C" { |
#endif |
/* === debug.c === */ |
void regprint (regex_t *r, FILE *d); |
static void s_print (register struct re_guts *g, FILE *d); |
static char *regchar (int ch); |
#ifdef __cplusplus |
} |
#endif |
/* ========= end header generated by ./mkh ========= */ |
/programs/develop/libraries/menuetlibc/src/libc/posix/regex/engine.c |
---|
0,0 → 1,1019 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
/* |
* The matching engine and friends. This file is #included by regexec.c |
* after suitable #defines of a variety of macros used herein, so that |
* different state representations can be used without duplicating masses |
* of code. |
*/ |
#ifdef SNAMES |
#define matcher smatcher |
#define fast sfast |
#define slow sslow |
#define dissect sdissect |
#define backref sbackref |
#define step sstep |
#define print sprint |
#define at sat |
#define match smat |
#endif |
#ifdef LNAMES |
#define matcher lmatcher |
#define fast lfast |
#define slow lslow |
#define dissect ldissect |
#define backref lbackref |
#define step lstep |
#define print lprint |
#define at lat |
#define match lmat |
#endif |
/* another structure passed up and down to avoid zillions of parameters */ |
struct match { |
struct re_guts *g; |
int eflags; |
regmatch_t *pmatch; /* [nsub+1] (0 element unused) */ |
char *offp; /* offsets work from here */ |
char *beginp; /* start of string -- virtual NUL precedes */ |
char *endp; /* end of string -- virtual NUL here */ |
char *coldp; /* can be no match starting before here */ |
char **lastpos; /* [nplus+1] */ |
STATEVARS; |
states st; /* current states */ |
states fresh; /* states for a fresh start */ |
states tmp; /* temporary */ |
states empty; /* empty set of states */ |
}; |
#include "engine.ih" |
#ifdef REDEBUG |
#define SP(t, s, c) print(m, t, s, c, stdout) |
#define AT(t, p1, p2, s1, s2) at(m, t, p1, p2, s1, s2) |
#define NOTE(str) { if (m->eflags®_TRACE) printf("=%s\n", (str)); } |
#else |
#define SP(t, s, c) /* nothing */ |
#define AT(t, p1, p2, s1, s2) /* nothing */ |
#define NOTE(s) /* nothing */ |
#endif |
/* |
- matcher - the actual matching engine |
== static int matcher(register struct re_guts *g, char *string, \ |
== size_t nmatch, regmatch_t pmatch[], int eflags); |
*/ |
static int /* 0 success, REG_NOMATCH failure */ |
matcher(g, string, nmatch, pmatch, eflags) |
register struct re_guts *g; |
char *string; |
size_t nmatch; |
regmatch_t pmatch[]; |
int eflags; |
{ |
register char *endp; |
register int i; |
struct match mv; |
register struct match *m = &mv; |
register char *dp; |
const register sopno gf = g->firststate+1; /* +1 for OEND */ |
const register sopno gl = g->laststate; |
char *start; |
char *stop; |
/* simplify the situation where possible */ |
if (g->cflags®_NOSUB) |
nmatch = 0; |
if (eflags®_STARTEND) { |
start = string + pmatch[0].rm_so; |
stop = string + pmatch[0].rm_eo; |
} else { |
start = string; |
stop = start + strlen(start); |
} |
if (stop < start) |
return(REG_INVARG); |
/* prescreening; this does wonders for this rather slow code */ |
if (g->must != NULL) { |
for (dp = start; dp < stop; dp++) |
if (*dp == g->must[0] && stop - dp >= g->mlen && |
memcmp(dp, g->must, (size_t)g->mlen) == 0) |
break; |
if (dp == stop) /* we didn't find g->must */ |
return(REG_NOMATCH); |
} |
/* match struct setup */ |
m->g = g; |
m->eflags = eflags; |
m->pmatch = NULL; |
m->lastpos = NULL; |
m->offp = string; |
m->beginp = start; |
m->endp = stop; |
STATESETUP(m, 4); |
SETUP(m->st); |
SETUP(m->fresh); |
SETUP(m->tmp); |
SETUP(m->empty); |
CLEAR(m->empty); |
/* this loop does only one repetition except for backrefs */ |
for (;;) { |
endp = fast(m, start, stop, gf, gl); |
if (endp == NULL) { /* a miss */ |
STATETEARDOWN(m); |
return(REG_NOMATCH); |
} |
if (nmatch == 0 && !g->backrefs) |
break; /* no further info needed */ |
/* where? */ |
assert(m->coldp != NULL); |
for (;;) { |
NOTE("finding start"); |
endp = slow(m, m->coldp, stop, gf, gl); |
if (endp != NULL) |
break; |
assert(m->coldp < m->endp); |
m->coldp++; |
} |
if (nmatch == 1 && !g->backrefs) |
break; /* no further info needed */ |
/* oh my, he wants the subexpressions... */ |
if (m->pmatch == NULL) |
m->pmatch = (regmatch_t *)malloc((m->g->nsub + 1) * |
sizeof(regmatch_t)); |
if (m->pmatch == NULL) { |
STATETEARDOWN(m); |
return(REG_ESPACE); |
} |
for (i = 1; i <= m->g->nsub; i++) |
m->pmatch[i].rm_so = m->pmatch[i].rm_eo = -1; |
if (!g->backrefs && !(m->eflags®_BACKR)) { |
NOTE("dissecting"); |
dp = dissect(m, m->coldp, endp, gf, gl); |
} else { |
if (g->nplus > 0 && m->lastpos == NULL) |
m->lastpos = (char **)malloc((g->nplus+1) * |
sizeof(char *)); |
if (g->nplus > 0 && m->lastpos == NULL) { |
free(m->pmatch); |
STATETEARDOWN(m); |
return(REG_ESPACE); |
} |
NOTE("backref dissect"); |
dp = backref(m, m->coldp, endp, gf, gl, (sopno)0); |
} |
if (dp != NULL) |
break; |
/* uh-oh... we couldn't find a subexpression-level match */ |
assert(g->backrefs); /* must be back references doing it */ |
assert(g->nplus == 0 || m->lastpos != NULL); |
for (;;) { |
if (dp != NULL || endp <= m->coldp) |
break; /* defeat */ |
NOTE("backoff"); |
endp = slow(m, m->coldp, endp-1, gf, gl); |
if (endp == NULL) |
break; /* defeat */ |
/* try it on a shorter possibility */ |
#ifndef NDEBUG |
for (i = 1; i <= m->g->nsub; i++) { |
assert(m->pmatch[i].rm_so == -1); |
assert(m->pmatch[i].rm_eo == -1); |
} |
#endif |
NOTE("backoff dissect"); |
dp = backref(m, m->coldp, endp, gf, gl, (sopno)0); |
} |
assert(dp == NULL || dp == endp); |
if (dp != NULL) /* found a shorter one */ |
break; |
/* despite initial appearances, there is no match here */ |
NOTE("false alarm"); |
start = m->coldp + 1; /* recycle starting later */ |
assert(start <= stop); |
} |
/* fill in the details if requested */ |
if (nmatch > 0) { |
pmatch[0].rm_so = m->coldp - m->offp; |
pmatch[0].rm_eo = endp - m->offp; |
} |
if (nmatch > 1) { |
assert(m->pmatch != NULL); |
for (i = 1; i < nmatch; i++) |
if (i <= m->g->nsub) |
pmatch[i] = m->pmatch[i]; |
else { |
pmatch[i].rm_so = -1; |
pmatch[i].rm_eo = -1; |
} |
} |
if (m->pmatch != NULL) |
free((char *)m->pmatch); |
if (m->lastpos != NULL) |
free((char *)m->lastpos); |
STATETEARDOWN(m); |
return(0); |
} |
/* |
- dissect - figure out what matched what, no back references |
== static char *dissect(register struct match *m, char *start, \ |
== char *stop, sopno startst, sopno stopst); |
*/ |
static char * /* == stop (success) always */ |
dissect(m, start, stop, startst, stopst) |
register struct match *m; |
char *start; |
char *stop; |
sopno startst; |
sopno stopst; |
{ |
register int i; |
register sopno ss; /* start sop of current subRE */ |
register sopno es; /* end sop of current subRE */ |
register char *sp; /* start of string matched by it */ |
register char *stp; /* string matched by it cannot pass here */ |
register char *rest; /* start of rest of string */ |
register char *tail; /* string unmatched by rest of RE */ |
register sopno ssub; /* start sop of subsubRE */ |
register sopno esub; /* end sop of subsubRE */ |
register char *ssp; /* start of string matched by subsubRE */ |
register char *sep; /* end of string matched by subsubRE */ |
register char *oldssp; /* previous ssp */ |
register char *dp; |
AT("diss", start, stop, startst, stopst); |
sp = start; |
for (ss = startst; ss < stopst; ss = es) { |
/* identify end of subRE */ |
es = ss; |
switch (OP(m->g->strip[es])) { |
case OPLUS_: |
case OQUEST_: |
es += OPND(m->g->strip[es]); |
break; |
case OCH_: |
while (OP(m->g->strip[es]) != O_CH) |
es += OPND(m->g->strip[es]); |
break; |
} |
es++; |
/* figure out what it matched */ |
switch (OP(m->g->strip[ss])) { |
case OEND: |
assert(nope); |
break; |
case OCHAR: |
sp++; |
break; |
case OBOL: |
case OEOL: |
case OBOW: |
case OEOW: |
break; |
case OANY: |
case OANYOF: |
sp++; |
break; |
case OBACK_: |
case O_BACK: |
assert(nope); |
break; |
/* cases where length of match is hard to find */ |
case OQUEST_: |
stp = stop; |
for (;;) { |
/* how long could this one be? */ |
rest = slow(m, sp, stp, ss, es); |
assert(rest != NULL); /* it did match */ |
/* could the rest match the rest? */ |
tail = slow(m, rest, stop, es, stopst); |
if (tail == stop) |
break; /* yes! */ |
/* no -- try a shorter match for this one */ |
stp = rest - 1; |
assert(stp >= sp); /* it did work */ |
} |
ssub = ss + 1; |
esub = es - 1; |
/* did innards match? */ |
if (slow(m, sp, rest, ssub, esub) != NULL) { |
dp = dissect(m, sp, rest, ssub, esub); |
assert(dp == rest); |
} else /* no */ |
assert(sp == rest); |
sp = rest; |
break; |
case OPLUS_: |
stp = stop; |
for (;;) { |
/* how long could this one be? */ |
rest = slow(m, sp, stp, ss, es); |
assert(rest != NULL); /* it did match */ |
/* could the rest match the rest? */ |
tail = slow(m, rest, stop, es, stopst); |
if (tail == stop) |
break; /* yes! */ |
/* no -- try a shorter match for this one */ |
stp = rest - 1; |
assert(stp >= sp); /* it did work */ |
} |
ssub = ss + 1; |
esub = es - 1; |
ssp = sp; |
oldssp = ssp; |
for (;;) { /* find last match of innards */ |
sep = slow(m, ssp, rest, ssub, esub); |
if (sep == NULL || sep == ssp) |
break; /* failed or matched null */ |
oldssp = ssp; /* on to next try */ |
ssp = sep; |
} |
if (sep == NULL) { |
/* last successful match */ |
sep = ssp; |
ssp = oldssp; |
} |
assert(sep == rest); /* must exhaust substring */ |
assert(slow(m, ssp, sep, ssub, esub) == rest); |
dp = dissect(m, ssp, sep, ssub, esub); |
assert(dp == sep); |
sp = rest; |
break; |
case OCH_: |
stp = stop; |
for (;;) { |
/* how long could this one be? */ |
rest = slow(m, sp, stp, ss, es); |
assert(rest != NULL); /* it did match */ |
/* could the rest match the rest? */ |
tail = slow(m, rest, stop, es, stopst); |
if (tail == stop) |
break; /* yes! */ |
/* no -- try a shorter match for this one */ |
stp = rest - 1; |
assert(stp >= sp); /* it did work */ |
} |
ssub = ss + 1; |
esub = ss + OPND(m->g->strip[ss]) - 1; |
assert(OP(m->g->strip[esub]) == OOR1); |
for (;;) { /* find first matching branch */ |
if (slow(m, sp, rest, ssub, esub) == rest) |
break; /* it matched all of it */ |
/* that one missed, try next one */ |
assert(OP(m->g->strip[esub]) == OOR1); |
esub++; |
assert(OP(m->g->strip[esub]) == OOR2); |
ssub = esub + 1; |
esub += OPND(m->g->strip[esub]); |
if (OP(m->g->strip[esub]) == OOR2) |
esub--; |
else |
assert(OP(m->g->strip[esub]) == O_CH); |
} |
dp = dissect(m, sp, rest, ssub, esub); |
assert(dp == rest); |
sp = rest; |
break; |
case O_PLUS: |
case O_QUEST: |
case OOR1: |
case OOR2: |
case O_CH: |
assert(nope); |
break; |
case OLPAREN: |
i = OPND(m->g->strip[ss]); |
assert(0 < i && i <= m->g->nsub); |
m->pmatch[i].rm_so = sp - m->offp; |
break; |
case ORPAREN: |
i = OPND(m->g->strip[ss]); |
assert(0 < i && i <= m->g->nsub); |
m->pmatch[i].rm_eo = sp - m->offp; |
break; |
default: /* uh oh */ |
assert(nope); |
break; |
} |
} |
assert(sp == stop); |
return(sp); |
} |
/* |
- backref - figure out what matched what, figuring in back references |
== static char *backref(register struct match *m, char *start, \ |
== char *stop, sopno startst, sopno stopst, sopno lev); |
*/ |
static char * /* == stop (success) or NULL (failure) */ |
backref(m, start, stop, startst, stopst, lev) |
register struct match *m; |
char *start; |
char *stop; |
sopno startst; |
sopno stopst; |
sopno lev; /* PLUS nesting level */ |
{ |
register int i; |
register sopno ss; /* start sop of current subRE */ |
register char *sp; /* start of string matched by it */ |
register sopno ssub; /* start sop of subsubRE */ |
register sopno esub; /* end sop of subsubRE */ |
register char *ssp; /* start of string matched by subsubRE */ |
register char *dp; |
register size_t len; |
register int hard; |
register sop s; |
register regoff_t offsave; |
register cset *cs; |
AT("back", start, stop, startst, stopst); |
sp = start; |
/* get as far as we can with easy stuff */ |
hard = 0; |
for (ss = startst; !hard && ss < stopst; ss++) |
switch (OP(s = m->g->strip[ss])) { |
case OCHAR: |
if (sp == stop || *sp++ != (char)OPND(s)) |
return(NULL); |
break; |
case OANY: |
if (sp == stop) |
return(NULL); |
sp++; |
break; |
case OANYOF: |
cs = &m->g->sets[OPND(s)]; |
if (sp == stop || !CHIN(cs, *sp++)) |
return(NULL); |
break; |
case OBOL: |
if ( (sp == m->beginp && !(m->eflags®_NOTBOL)) || |
(sp < m->endp && *(sp-1) == '\n' && |
(m->g->cflags®_NEWLINE)) ) |
{ /* yes */ } |
else |
return(NULL); |
break; |
case OEOL: |
if ( (sp == m->endp && !(m->eflags®_NOTEOL)) || |
(sp < m->endp && *sp == '\n' && |
(m->g->cflags®_NEWLINE)) ) |
{ /* yes */ } |
else |
return(NULL); |
break; |
case OBOW: |
if (( (sp == m->beginp && !(m->eflags®_NOTBOL)) || |
(sp < m->endp && *(sp-1) == '\n' && |
(m->g->cflags®_NEWLINE)) || |
(sp > m->beginp && |
!ISWORD(*(sp-1))) ) && |
(sp < m->endp && ISWORD(*sp)) ) |
{ /* yes */ } |
else |
return(NULL); |
break; |
case OEOW: |
if (( (sp == m->endp && !(m->eflags®_NOTEOL)) || |
(sp < m->endp && *sp == '\n' && |
(m->g->cflags®_NEWLINE)) || |
(sp < m->endp && !ISWORD(*sp)) ) && |
(sp > m->beginp && ISWORD(*(sp-1))) ) |
{ /* yes */ } |
else |
return(NULL); |
break; |
case O_QUEST: |
break; |
case OOR1: /* matches null but needs to skip */ |
ss++; |
s = m->g->strip[ss]; |
do { |
assert(OP(s) == OOR2); |
ss += OPND(s); |
} while (OP(s = m->g->strip[ss]) != O_CH); |
/* note that the ss++ gets us past the O_CH */ |
break; |
default: /* have to make a choice */ |
hard = 1; |
break; |
} |
if (!hard) { /* that was it! */ |
if (sp != stop) |
return(NULL); |
return(sp); |
} |
ss--; /* adjust for the for's final increment */ |
/* the hard stuff */ |
AT("hard", sp, stop, ss, stopst); |
s = m->g->strip[ss]; |
switch (OP(s)) { |
case OBACK_: /* the vilest depths */ |
i = OPND(s); |
assert(0 < i && i <= m->g->nsub); |
if (m->pmatch[i].rm_eo == -1) |
return(NULL); |
assert(m->pmatch[i].rm_so != -1); |
len = m->pmatch[i].rm_eo - m->pmatch[i].rm_so; |
assert(stop - m->beginp >= len); |
if (sp > stop - len) |
return(NULL); /* not enough left to match */ |
ssp = m->offp + m->pmatch[i].rm_so; |
if (memcmp(sp, ssp, len) != 0) |
return(NULL); |
while (m->g->strip[ss] != SOP(O_BACK, i)) |
ss++; |
return(backref(m, sp+len, stop, ss+1, stopst, lev)); |
break; |
case OQUEST_: /* to null or not */ |
dp = backref(m, sp, stop, ss+1, stopst, lev); |
if (dp != NULL) |
return(dp); /* not */ |
return(backref(m, sp, stop, ss+OPND(s)+1, stopst, lev)); |
break; |
case OPLUS_: |
assert(m->lastpos != NULL); |
assert(lev+1 <= m->g->nplus); |
m->lastpos[lev+1] = sp; |
return(backref(m, sp, stop, ss+1, stopst, lev+1)); |
break; |
case O_PLUS: |
if (sp == m->lastpos[lev]) /* last pass matched null */ |
return(backref(m, sp, stop, ss+1, stopst, lev-1)); |
/* try another pass */ |
m->lastpos[lev] = sp; |
dp = backref(m, sp, stop, ss-OPND(s)+1, stopst, lev); |
if (dp == NULL) |
return(backref(m, sp, stop, ss+1, stopst, lev-1)); |
else |
return(dp); |
break; |
case OCH_: /* find the right one, if any */ |
ssub = ss + 1; |
esub = ss + OPND(s) - 1; |
assert(OP(m->g->strip[esub]) == OOR1); |
for (;;) { /* find first matching branch */ |
dp = backref(m, sp, stop, ssub, esub, lev); |
if (dp != NULL) |
return(dp); |
/* that one missed, try next one */ |
if (OP(m->g->strip[esub]) == O_CH) |
return(NULL); /* there is none */ |
esub++; |
assert(OP(m->g->strip[esub]) == OOR2); |
ssub = esub + 1; |
esub += OPND(m->g->strip[esub]); |
if (OP(m->g->strip[esub]) == OOR2) |
esub--; |
else |
assert(OP(m->g->strip[esub]) == O_CH); |
} |
break; |
case OLPAREN: /* must undo assignment if rest fails */ |
i = OPND(s); |
assert(0 < i && i <= m->g->nsub); |
offsave = m->pmatch[i].rm_so; |
m->pmatch[i].rm_so = sp - m->offp; |
dp = backref(m, sp, stop, ss+1, stopst, lev); |
if (dp != NULL) |
return(dp); |
m->pmatch[i].rm_so = offsave; |
return(NULL); |
break; |
case ORPAREN: /* must undo assignment if rest fails */ |
i = OPND(s); |
assert(0 < i && i <= m->g->nsub); |
offsave = m->pmatch[i].rm_eo; |
m->pmatch[i].rm_eo = sp - m->offp; |
dp = backref(m, sp, stop, ss+1, stopst, lev); |
if (dp != NULL) |
return(dp); |
m->pmatch[i].rm_eo = offsave; |
return(NULL); |
break; |
default: /* uh oh */ |
assert(nope); |
break; |
} |
/* "can't happen" */ |
assert(nope); |
/* NOTREACHED */ |
} |
/* |
- fast - step through the string at top speed |
== static char *fast(register struct match *m, char *start, \ |
== char *stop, sopno startst, sopno stopst); |
*/ |
static char * /* where tentative match ended, or NULL */ |
fast(m, start, stop, startst, stopst) |
register struct match *m; |
char *start; |
char *stop; |
sopno startst; |
sopno stopst; |
{ |
register states st = m->st; |
register states fresh = m->fresh; |
register states tmp = m->tmp; |
register char *p = start; |
register int c = (start == m->beginp) ? OUT : *(start-1); |
register int lastc; /* previous c */ |
register int flagch; |
register int i; |
register char *coldp; /* last p after which no match was underway */ |
CLEAR(st); |
SET1(st, startst); |
st = step(m->g, startst, stopst, st, NOTHING, st); |
ASSIGN(fresh, st); |
SP("start", st, *p); |
coldp = NULL; |
for (;;) { |
/* next character */ |
lastc = c; |
c = (p == m->endp) ? OUT : *p; |
if (EQ(st, fresh)) |
coldp = p; |
/* is there an EOL and/or BOL between lastc and c? */ |
flagch = '\0'; |
i = 0; |
if ( (lastc == '\n' && m->g->cflags®_NEWLINE) || |
(lastc == OUT && !(m->eflags®_NOTBOL)) ) { |
flagch = BOL; |
i = m->g->nbol; |
} |
if ( (c == '\n' && m->g->cflags®_NEWLINE) || |
(c == OUT && !(m->eflags®_NOTEOL)) ) { |
flagch = (flagch == BOL) ? BOLEOL : EOL; |
i += m->g->neol; |
} |
if (i != 0) { |
for (; i > 0; i--) |
st = step(m->g, startst, stopst, st, flagch, st); |
SP("boleol", st, c); |
} |
/* how about a word boundary? */ |
if ( (flagch == BOL || (lastc != OUT && !ISWORD(lastc))) && |
(c != OUT && ISWORD(c)) ) { |
flagch = BOW; |
} |
if ( (lastc != OUT && ISWORD(lastc)) && |
(flagch == EOL || (c != OUT && !ISWORD(c))) ) { |
flagch = EOW; |
} |
if (flagch == BOW || flagch == EOW) { |
st = step(m->g, startst, stopst, st, flagch, st); |
SP("boweow", st, c); |
} |
/* are we done? */ |
if (ISSET(st, stopst) || p == stop) |
break; /* NOTE BREAK OUT */ |
/* no, we must deal with this character */ |
ASSIGN(tmp, st); |
ASSIGN(st, fresh); |
assert(c != OUT); |
st = step(m->g, startst, stopst, tmp, c, st); |
SP("aft", st, c); |
assert(EQ(step(m->g, startst, stopst, st, NOTHING, st), st)); |
p++; |
} |
assert(coldp != NULL); |
m->coldp = coldp; |
if (ISSET(st, stopst)) |
return(p+1); |
else |
return(NULL); |
} |
/* |
- slow - step through the string more deliberately |
== static char *slow(register struct match *m, char *start, \ |
== char *stop, sopno startst, sopno stopst); |
*/ |
static char * /* where it ended */ |
slow(m, start, stop, startst, stopst) |
register struct match *m; |
char *start; |
char *stop; |
sopno startst; |
sopno stopst; |
{ |
register states st = m->st; |
register states empty = m->empty; |
register states tmp = m->tmp; |
register char *p = start; |
register int c = (start == m->beginp) ? OUT : *(start-1); |
register int lastc; /* previous c */ |
register int flagch; |
register int i; |
register char *matchp; /* last p at which a match ended */ |
AT("slow", start, stop, startst, stopst); |
CLEAR(st); |
SET1(st, startst); |
SP("sstart", st, *p); |
st = step(m->g, startst, stopst, st, NOTHING, st); |
matchp = NULL; |
for (;;) { |
/* next character */ |
lastc = c; |
c = (p == m->endp) ? OUT : *p; |
/* is there an EOL and/or BOL between lastc and c? */ |
flagch = '\0'; |
i = 0; |
if ( (lastc == '\n' && m->g->cflags®_NEWLINE) || |
(lastc == OUT && !(m->eflags®_NOTBOL)) ) { |
flagch = BOL; |
i = m->g->nbol; |
} |
if ( (c == '\n' && m->g->cflags®_NEWLINE) || |
(c == OUT && !(m->eflags®_NOTEOL)) ) { |
flagch = (flagch == BOL) ? BOLEOL : EOL; |
i += m->g->neol; |
} |
if (i != 0) { |
for (; i > 0; i--) |
st = step(m->g, startst, stopst, st, flagch, st); |
SP("sboleol", st, c); |
} |
/* how about a word boundary? */ |
if ( (flagch == BOL || (lastc != OUT && !ISWORD(lastc))) && |
(c != OUT && ISWORD(c)) ) { |
flagch = BOW; |
} |
if ( (lastc != OUT && ISWORD(lastc)) && |
(flagch == EOL || (c != OUT && !ISWORD(c))) ) { |
flagch = EOW; |
} |
if (flagch == BOW || flagch == EOW) { |
st = step(m->g, startst, stopst, st, flagch, st); |
SP("sboweow", st, c); |
} |
/* are we done? */ |
if (ISSET(st, stopst)) |
matchp = p; |
if (EQ(st, empty) || p == stop) |
break; /* NOTE BREAK OUT */ |
/* no, we must deal with this character */ |
ASSIGN(tmp, st); |
ASSIGN(st, empty); |
assert(c != OUT); |
st = step(m->g, startst, stopst, tmp, c, st); |
SP("saft", st, c); |
assert(EQ(step(m->g, startst, stopst, st, NOTHING, st), st)); |
p++; |
} |
return(matchp); |
} |
/* |
- step - map set of states reachable before char to set reachable after |
== static states step(register struct re_guts *g, sopno start, sopno stop, \ |
== register states bef, int ch, register states aft); |
== #define BOL (OUT+1) |
== #define EOL (BOL+1) |
== #define BOLEOL (BOL+2) |
== #define NOTHING (BOL+3) |
== #define BOW (BOL+4) |
== #define EOW (BOL+5) |
== #define CODEMAX (BOL+5) // highest code used |
== #define NONCHAR(c) ((c) > CHAR_MAX) |
== #define NNONCHAR (CODEMAX-CHAR_MAX) |
*/ |
static states |
step(g, start, stop, bef, ch, aft) |
register struct re_guts *g; |
sopno start; /* start state within strip */ |
sopno stop; /* state after stop state within strip */ |
register states bef; /* states reachable before */ |
int ch; /* character or NONCHAR code */ |
register states aft; /* states already known reachable after */ |
{ |
register cset *cs; |
register sop s; |
register sopno pc; |
register onestate here; /* note, macros know this name */ |
register sopno look; |
register int i; |
for (pc = start, INIT(here, pc); pc != stop; pc++, INC(here)) { |
s = g->strip[pc]; |
switch (OP(s)) { |
case OEND: |
assert(pc == stop-1); |
break; |
case OCHAR: |
/* only characters can match */ |
assert(!NONCHAR(ch) || ch != (char)OPND(s)); |
if (ch == (char)OPND(s)) |
FWD(aft, bef, 1); |
break; |
case OBOL: |
if (ch == BOL || ch == BOLEOL) |
FWD(aft, bef, 1); |
break; |
case OEOL: |
if (ch == EOL || ch == BOLEOL) |
FWD(aft, bef, 1); |
break; |
case OBOW: |
if (ch == BOW) |
FWD(aft, bef, 1); |
break; |
case OEOW: |
if (ch == EOW) |
FWD(aft, bef, 1); |
break; |
case OANY: |
if (!NONCHAR(ch)) |
FWD(aft, bef, 1); |
break; |
case OANYOF: |
cs = &g->sets[OPND(s)]; |
if (!NONCHAR(ch) && CHIN(cs, ch)) |
FWD(aft, bef, 1); |
break; |
case OBACK_: /* ignored here */ |
case O_BACK: |
FWD(aft, aft, 1); |
break; |
case OPLUS_: /* forward, this is just an empty */ |
FWD(aft, aft, 1); |
break; |
case O_PLUS: /* both forward and back */ |
FWD(aft, aft, 1); |
i = ISSETBACK(aft, OPND(s)); |
BACK(aft, aft, OPND(s)); |
if (!i && ISSETBACK(aft, OPND(s))) { |
/* oho, must reconsider loop body */ |
pc -= OPND(s) + 1; |
INIT(here, pc); |
} |
break; |
case OQUEST_: /* two branches, both forward */ |
FWD(aft, aft, 1); |
FWD(aft, aft, OPND(s)); |
break; |
case O_QUEST: /* just an empty */ |
FWD(aft, aft, 1); |
break; |
case OLPAREN: /* not significant here */ |
case ORPAREN: |
FWD(aft, aft, 1); |
break; |
case OCH_: /* mark the first two branches */ |
FWD(aft, aft, 1); |
assert(OP(g->strip[pc+OPND(s)]) == OOR2); |
FWD(aft, aft, OPND(s)); |
break; |
case OOR1: /* done a branch, find the O_CH */ |
if (ISSTATEIN(aft, here)) { |
for (look = 1; |
OP(s = g->strip[pc+look]) != O_CH; |
look += OPND(s)) |
assert(OP(s) == OOR2); |
FWD(aft, aft, look); |
} |
break; |
case OOR2: /* propagate OCH_'s marking */ |
FWD(aft, aft, 1); |
if (OP(g->strip[pc+OPND(s)]) != O_CH) { |
assert(OP(g->strip[pc+OPND(s)]) == OOR2); |
FWD(aft, aft, OPND(s)); |
} |
break; |
case O_CH: /* just empty */ |
FWD(aft, aft, 1); |
break; |
default: /* ooooops... */ |
assert(nope); |
break; |
} |
} |
return(aft); |
} |
#ifdef REDEBUG |
/* |
- print - print a set of states |
== #ifdef REDEBUG |
== static void print(struct match *m, char *caption, states st, \ |
== int ch, FILE *d); |
== #endif |
*/ |
static void |
print(m, caption, st, ch, d) |
struct match *m; |
char *caption; |
states st; |
int ch; |
FILE *d; |
{ |
register struct re_guts *g = m->g; |
register int i; |
register int first = 1; |
if (!(m->eflags®_TRACE)) |
return; |
fprintf(d, "%s", caption); |
if (ch != '\0') |
fprintf(d, " %s", pchar(ch)); |
for (i = 0; i < g->nstates; i++) |
if (ISSET(st, i)) { |
fprintf(d, "%s%d", (first) ? "\t" : ", ", i); |
first = 0; |
} |
fprintf(d, "\n"); |
} |
/* |
- at - print current situation |
== #ifdef REDEBUG |
== static void at(struct match *m, char *title, char *start, char *stop, \ |
== sopno startst, sopno stopst); |
== #endif |
*/ |
static void |
at(m, title, start, stop, startst, stopst) |
struct match *m; |
char *title; |
char *start; |
char *stop; |
sopno startst; |
sopno stopst; |
{ |
if (!(m->eflags®_TRACE)) |
return; |
printf("%s %s-", title, pchar(*start)); |
printf("%s ", pchar(*stop)); |
printf("%ld-%ld\n", (long)startst, (long)stopst); |
} |
#ifndef PCHARDONE |
#define PCHARDONE /* never again */ |
/* |
- pchar - make a character printable |
== #ifdef REDEBUG |
== static char *pchar(int ch); |
== #endif |
* |
* Is this identical to regchar() over in debug.c? Well, yes. But a |
* duplicate here avoids having a debugging-capable regexec.o tied to |
* a matching debug.o, and this is convenient. It all disappears in |
* the non-debug compilation anyway, so it doesn't matter much. |
*/ |
static char * /* -> representation */ |
pchar(ch) |
int ch; |
{ |
static char pbuf[10]; |
if (isprint(ch) || ch == ' ') |
sprintf(pbuf, "%c", ch); |
else |
sprintf(pbuf, "\\%o", ch); |
return(pbuf); |
} |
#endif |
#endif |
#undef matcher |
#undef fast |
#undef slow |
#undef dissect |
#undef backref |
#undef step |
#undef print |
#undef at |
#undef match |
/programs/develop/libraries/menuetlibc/src/libc/posix/regex/engine.ih |
---|
0,0 → 1,35 |
/* ========= begin header generated by ./mkh ========= */ |
#ifdef __cplusplus |
extern "C" { |
#endif |
/* === engine.c === */ |
static int matcher (register struct re_guts *g, char *string, size_t nmatch, regmatch_t pmatch[], int eflags); |
static char *dissect (register struct match *m, char *start, char *stop, sopno startst, sopno stopst); |
static char *backref (register struct match *m, char *start, char *stop, sopno startst, sopno stopst, sopno lev); |
static char *fast (register struct match *m, char *start, char *stop, sopno startst, sopno stopst); |
static char *slow (register struct match *m, char *start, char *stop, sopno startst, sopno stopst); |
static states step (register struct re_guts *g, sopno start, sopno stop, register states bef, int ch, register states aft); |
#define BOL (OUT+1) |
#define EOL (BOL+1) |
#define BOLEOL (BOL+2) |
#define NOTHING (BOL+3) |
#define BOW (BOL+4) |
#define EOW (BOL+5) |
#define CODEMAX (BOL+5) /* highest code used */ |
#define NONCHAR(c) ((c) > CHAR_MAX) |
#define NNONCHAR (CODEMAX-CHAR_MAX) |
#ifdef REDEBUG |
static void print (struct match *m, char *caption, states st, int ch, FILE *d); |
#endif |
#ifdef REDEBUG |
static void at (struct match *m, char *title, char *start, char *stop, sopno startst, sopno stopst); |
#endif |
#ifdef REDEBUG |
static char *pchar (int ch); |
#endif |
#ifdef __cplusplus |
} |
#endif |
/* ========= end header generated by ./mkh ========= */ |
/programs/develop/libraries/menuetlibc/src/libc/posix/regex/main.c |
---|
0,0 → 1,511 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <stdio.h> |
#include <string.h> |
#include <sys/types.h> |
#include <regex.h> |
#include <assert.h> |
#include "main.ih" |
char *progname; |
int debug = 0; |
int line = 0; |
int status = 0; |
int copts = REG_EXTENDED; |
int eopts = 0; |
regoff_t startoff = 0; |
regoff_t endoff = 0; |
extern int split(); |
extern void regprint(); |
/* |
- main - do the simple case, hand off to regress() for regression |
*/ |
main(argc, argv) |
int argc; |
char *argv[]; |
{ |
regex_t re; |
# define NS 10 |
regmatch_t subs[NS]; |
char erbuf[100]; |
int err; |
size_t len; |
int c; |
int errflg = 0; |
register int i; |
extern int optind; |
extern char *optarg; |
progname = argv[0]; |
while ((c = getopt(argc, argv, "c:e:S:E:x")) != EOF) |
switch (c) { |
case 'c': /* compile options */ |
copts = options('c', optarg); |
break; |
case 'e': /* execute options */ |
eopts = options('e', optarg); |
break; |
case 'S': /* start offset */ |
startoff = (regoff_t)atoi(optarg); |
break; |
case 'E': /* end offset */ |
endoff = (regoff_t)atoi(optarg); |
break; |
case 'x': /* Debugging. */ |
debug++; |
break; |
case '?': |
default: |
errflg++; |
break; |
} |
if (errflg) { |
fprintf(stderr, "usage: %s ", progname); |
fprintf(stderr, "[-c copt][-C][-d] [re]\n"); |
exit(2); |
} |
if (optind >= argc) { |
regress(stdin); |
exit(status); |
} |
err = regcomp(&re, argv[optind++], copts); |
if (err) { |
len = regerror(err, &re, erbuf, sizeof(erbuf)); |
fprintf(stderr, "error %s, %d/%d `%s'\n", |
eprint(err), len, sizeof(erbuf), erbuf); |
exit(status); |
} |
regprint(&re, stdout); |
if (optind >= argc) { |
regfree(&re); |
exit(status); |
} |
if (eopts®_STARTEND) { |
subs[0].rm_so = startoff; |
subs[0].rm_eo = strlen(argv[optind]) - endoff; |
} |
err = regexec(&re, argv[optind], (size_t)NS, subs, eopts); |
if (err) { |
len = regerror(err, &re, erbuf, sizeof(erbuf)); |
fprintf(stderr, "error %s, %d/%d `%s'\n", |
eprint(err), len, sizeof(erbuf), erbuf); |
exit(status); |
} |
if (!(copts®_NOSUB)) { |
len = (int)(subs[0].rm_eo - subs[0].rm_so); |
if (subs[0].rm_so != -1) { |
if (len != 0) |
printf("match `%.*s'\n", len, |
argv[optind] + subs[0].rm_so); |
else |
printf("match `'@%.1s\n", |
argv[optind] + subs[0].rm_so); |
} |
for (i = 1; i < NS; i++) |
if (subs[i].rm_so != -1) |
printf("(%d) `%.*s'\n", i, |
(int)(subs[i].rm_eo - subs[i].rm_so), |
argv[optind] + subs[i].rm_so); |
} |
exit(status); |
} |
/* |
- regress - main loop of regression test |
== void regress(FILE *in); |
*/ |
void |
regress(in) |
FILE *in; |
{ |
char inbuf[1000]; |
# define MAXF 10 |
char *f[MAXF]; |
int nf; |
int i; |
char erbuf[100]; |
size_t ne; |
char *badpat = "invalid regular expression"; |
# define SHORT 10 |
char *bpname = "REG_BADPAT"; |
regex_t re; |
while (fgets(inbuf, sizeof(inbuf), in) != NULL) { |
line++; |
if (inbuf[0] == '#' || inbuf[0] == '\n') |
continue; /* NOTE CONTINUE */ |
inbuf[strlen(inbuf)-1] = '\0'; /* get rid of stupid \n */ |
if (debug) |
fprintf(stdout, "%d:\n", line); |
nf = split(inbuf, f, MAXF, "\t\t"); |
if (nf < 3) { |
fprintf(stderr, "bad input, line %d\n", line); |
exit(1); |
} |
for (i = 0; i < nf; i++) |
if (strcmp(f[i], "\"\"") == 0) |
f[i] = ""; |
if (nf <= 3) |
f[3] = NULL; |
if (nf <= 4) |
f[4] = NULL; |
try(f[0], f[1], f[2], f[3], f[4], options('c', f[1])); |
if (opt('&', f[1])) /* try with either type of RE */ |
try(f[0], f[1], f[2], f[3], f[4], |
options('c', f[1]) &~ REG_EXTENDED); |
} |
ne = regerror(REG_BADPAT, (regex_t *)NULL, erbuf, sizeof(erbuf)); |
if (strcmp(erbuf, badpat) != 0 || ne != strlen(badpat)+1) { |
fprintf(stderr, "end: regerror() test gave `%s' not `%s'\n", |
erbuf, badpat); |
status = 1; |
} |
ne = regerror(REG_BADPAT, (regex_t *)NULL, erbuf, (size_t)SHORT); |
if (strncmp(erbuf, badpat, SHORT-1) != 0 || erbuf[SHORT-1] != '\0' || |
ne != strlen(badpat)+1) { |
fprintf(stderr, "end: regerror() short test gave `%s' not `%.*s'\n", |
erbuf, SHORT-1, badpat); |
status = 1; |
} |
ne = regerror(REG_ITOA|REG_BADPAT, (regex_t *)NULL, erbuf, sizeof(erbuf)); |
if (strcmp(erbuf, bpname) != 0 || ne != strlen(bpname)+1) { |
fprintf(stderr, "end: regerror() ITOA test gave `%s' not `%s'\n", |
erbuf, bpname); |
status = 1; |
} |
re.re_endp = bpname; |
ne = regerror(REG_ATOI, &re, erbuf, sizeof(erbuf)); |
if (atoi(erbuf) != (int)REG_BADPAT) { |
fprintf(stderr, "end: regerror() ATOI test gave `%s' not `%ld'\n", |
erbuf, (long)REG_BADPAT); |
status = 1; |
} else if (ne != strlen(erbuf)+1) { |
fprintf(stderr, "end: regerror() ATOI test len(`%s') = %ld\n", |
erbuf, (long)REG_BADPAT); |
status = 1; |
} |
} |
/* |
- try - try it, and report on problems |
== void try(char *f0, char *f1, char *f2, char *f3, char *f4, int opts); |
*/ |
void |
try(f0, f1, f2, f3, f4, opts) |
char *f0; |
char *f1; |
char *f2; |
char *f3; |
char *f4; |
int opts; /* may not match f1 */ |
{ |
regex_t re; |
# define NSUBS 10 |
regmatch_t subs[NSUBS]; |
# define NSHOULD 15 |
char *should[NSHOULD]; |
int nshould; |
char erbuf[100]; |
int err; |
int len; |
char *type = (opts & REG_EXTENDED) ? "ERE" : "BRE"; |
register int i; |
char *grump; |
char f0copy[1000]; |
char f2copy[1000]; |
strcpy(f0copy, f0); |
re.re_endp = (opts®_PEND) ? f0copy + strlen(f0copy) : NULL; |
fixstr(f0copy); |
err = regcomp(&re, f0copy, opts); |
if (err != 0 && (!opt('C', f1) || err != efind(f2))) { |
/* unexpected error or wrong error */ |
len = regerror(err, &re, erbuf, sizeof(erbuf)); |
fprintf(stderr, "%d: %s error %s, %d/%d `%s'\n", |
line, type, eprint(err), len, |
sizeof(erbuf), erbuf); |
status = 1; |
} else if (err == 0 && opt('C', f1)) { |
/* unexpected success */ |
fprintf(stderr, "%d: %s should have given REG_%s\n", |
line, type, f2); |
status = 1; |
err = 1; /* so we won't try regexec */ |
} |
if (err != 0) { |
regfree(&re); |
return; |
} |
strcpy(f2copy, f2); |
fixstr(f2copy); |
if (options('e', f1)®_STARTEND) { |
if (strchr(f2, '(') == NULL || strchr(f2, ')') == NULL) |
fprintf(stderr, "%d: bad STARTEND syntax\n", line); |
subs[0].rm_so = strchr(f2, '(') - f2 + 1; |
subs[0].rm_eo = strchr(f2, ')') - f2; |
} |
err = regexec(&re, f2copy, NSUBS, subs, options('e', f1)); |
if (err != 0 && (f3 != NULL || err != REG_NOMATCH)) { |
/* unexpected error or wrong error */ |
len = regerror(err, &re, erbuf, sizeof(erbuf)); |
fprintf(stderr, "%d: %s exec error %s, %d/%d `%s'\n", |
line, type, eprint(err), len, |
sizeof(erbuf), erbuf); |
status = 1; |
} else if (err != 0) { |
/* nothing more to check */ |
} else if (f3 == NULL) { |
/* unexpected success */ |
fprintf(stderr, "%d: %s exec should have failed\n", |
line, type); |
status = 1; |
err = 1; /* just on principle */ |
} else if (opts®_NOSUB) { |
/* nothing more to check */ |
} else if ((grump = check(f2, subs[0], f3)) != NULL) { |
fprintf(stderr, "%d: %s %s\n", line, type, grump); |
status = 1; |
err = 1; |
} |
if (err != 0 || f4 == NULL) { |
regfree(&re); |
return; |
} |
for (i = 1; i < NSHOULD; i++) |
should[i] = NULL; |
nshould = split(f4, should+1, NSHOULD-1, ","); |
if (nshould == 0) { |
nshould = 1; |
should[1] = ""; |
} |
for (i = 1; i < NSUBS; i++) { |
grump = check(f2, subs[i], should[i]); |
if (grump != NULL) { |
fprintf(stderr, "%d: %s $%d %s\n", line, |
type, i, grump); |
status = 1; |
err = 1; |
} |
} |
regfree(&re); |
} |
/* |
- options - pick options out of a regression-test string |
== int options(int type, char *s); |
*/ |
int |
options(type, s) |
int type; /* 'c' compile, 'e' exec */ |
char *s; |
{ |
register char *p; |
register int o = (type == 'c') ? copts : eopts; |
register char *legal = (type == 'c') ? "bisnmp" : "^$#tl"; |
for (p = s; *p != '\0'; p++) |
if (strchr(legal, *p) != NULL) |
switch (*p) { |
case 'b': |
o &= ~REG_EXTENDED; |
break; |
case 'i': |
o |= REG_ICASE; |
break; |
case 's': |
o |= REG_NOSUB; |
break; |
case 'n': |
o |= REG_NEWLINE; |
break; |
case 'm': |
o &= ~REG_EXTENDED; |
o |= REG_NOSPEC; |
break; |
case 'p': |
o |= REG_PEND; |
break; |
case '^': |
o |= REG_NOTBOL; |
break; |
case '$': |
o |= REG_NOTEOL; |
break; |
case '#': |
o |= REG_STARTEND; |
break; |
case 't': /* trace */ |
o |= REG_TRACE; |
break; |
case 'l': /* force long representation */ |
o |= REG_LARGE; |
break; |
case 'r': /* force backref use */ |
o |= REG_BACKR; |
break; |
} |
return(o); |
} |
/* |
- opt - is a particular option in a regression string? |
== int opt(int c, char *s); |
*/ |
int /* predicate */ |
opt(c, s) |
int c; |
char *s; |
{ |
return(strchr(s, c) != NULL); |
} |
/* |
- fixstr - transform magic characters in strings |
== void fixstr(register char *p); |
*/ |
void |
fixstr(p) |
register char *p; |
{ |
if (p == NULL) |
return; |
for (; *p != '\0'; p++) |
if (*p == 'N') |
*p = '\n'; |
else if (*p == 'T') |
*p = '\t'; |
else if (*p == 'S') |
*p = ' '; |
else if (*p == 'Z') |
*p = '\0'; |
} |
/* |
- check - check a substring match |
== char *check(char *str, regmatch_t sub, char *should); |
*/ |
char * /* NULL or complaint */ |
check(str, sub, should) |
char *str; |
regmatch_t sub; |
char *should; |
{ |
register int len; |
register int shlen; |
register char *p; |
static char grump[500]; |
register char *at = NULL; |
if (should != NULL && strcmp(should, "-") == 0) |
should = NULL; |
if (should != NULL && should[0] == '@') { |
at = should + 1; |
should = ""; |
} |
/* check rm_so and rm_eo for consistency */ |
if (sub.rm_so > sub.rm_eo || (sub.rm_so == -1 && sub.rm_eo != -1) || |
(sub.rm_so != -1 && sub.rm_eo == -1) || |
(sub.rm_so != -1 && sub.rm_so < 0) || |
(sub.rm_eo != -1 && sub.rm_eo < 0) ) { |
sprintf(grump, "start %ld end %ld", (long)sub.rm_so, |
(long)sub.rm_eo); |
return(grump); |
} |
/* check for no match */ |
if (sub.rm_so == -1 && should == NULL) |
return(NULL); |
if (sub.rm_so == -1) |
return("did not match"); |
/* check for in range */ |
if (sub.rm_eo > strlen(str)) { |
sprintf(grump, "start %ld end %ld, past end of string", |
(long)sub.rm_so, (long)sub.rm_eo); |
return(grump); |
} |
len = (int)(sub.rm_eo - sub.rm_so); |
shlen = (int)strlen(should); |
p = str + sub.rm_so; |
/* check for not supposed to match */ |
if (should == NULL) { |
sprintf(grump, "matched `%.*s'", len, p); |
return(grump); |
} |
/* check for wrong match */ |
if (len != shlen || strncmp(p, should, (size_t)shlen) != 0) { |
sprintf(grump, "matched `%.*s' instead", len, p); |
return(grump); |
} |
if (shlen > 0) |
return(NULL); |
/* check null match in right place */ |
if (at == NULL) |
return(NULL); |
shlen = strlen(at); |
if (shlen == 0) |
shlen = 1; /* force check for end-of-string */ |
if (strncmp(p, at, shlen) != 0) { |
sprintf(grump, "matched null at `%.20s'", p); |
return(grump); |
} |
return(NULL); |
} |
/* |
- eprint - convert error number to name |
== static char *eprint(int err); |
*/ |
static char * |
eprint(err) |
int err; |
{ |
static char epbuf[100]; |
size_t len; |
len = regerror(REG_ITOA|err, (regex_t *)NULL, epbuf, sizeof(epbuf)); |
assert(len <= sizeof(epbuf)); |
return(epbuf); |
} |
/* |
- efind - convert error name to number |
== static int efind(char *name); |
*/ |
static int |
efind(name) |
char *name; |
{ |
static char efbuf[100]; |
size_t n; |
regex_t re; |
sprintf(efbuf, "REG_%s", name); |
assert(strlen(efbuf) < sizeof(efbuf)); |
re.re_endp = efbuf; |
(void) regerror(REG_ATOI, &re, efbuf, sizeof(efbuf)); |
return(atoi(efbuf)); |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/regex/main.ih |
---|
0,0 → 1,19 |
/* ========= begin header generated by ./mkh ========= */ |
#ifdef __cplusplus |
extern "C" { |
#endif |
/* === main.c === */ |
void regress (FILE *in); |
void try (char *f0, char *f1, char *f2, char *f3, char *f4, int opts); |
int options (int type, char *s); |
int opt (int c, char *s); |
void fixstr (register char *p); |
char *check (char *str, regmatch_t sub, char *should); |
static char *eprint (int err); |
static int efind (char *name); |
#ifdef __cplusplus |
} |
#endif |
/* ========= end header generated by ./mkh ========= */ |
/programs/develop/libraries/menuetlibc/src/libc/posix/regex/regcomp.c |
---|
0,0 → 1,1606 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <sys/types.h> |
#include <stdio.h> |
#include <string.h> |
#include <ctype.h> |
#include <limits.h> |
#include <stdlib.h> |
#include <regex.h> |
#include "utils.h" |
#include "regex2.h" |
#include "cclass.h" |
#include "cname.h" |
/* |
* parse structure, passed up and down to avoid global variables and |
* other clumsinesses |
*/ |
struct parse { |
char *next; /* next character in RE */ |
char *end; /* end of string (-> NUL normally) */ |
int error; /* has an error been seen? */ |
sop *strip; /* malloced strip */ |
sopno ssize; /* malloced strip size (allocated) */ |
sopno slen; /* malloced strip length (used) */ |
int ncsalloc; /* number of csets allocated */ |
struct re_guts *g; |
# define NPAREN 10 /* we need to remember () 1-9 for back refs */ |
sopno pbegin[NPAREN]; /* -> ( ([0] unused) */ |
sopno pend[NPAREN]; /* -> ) ([0] unused) */ |
}; |
#include "regcomp.ih" |
static char nuls[10]; /* place to point scanner in event of error */ |
/* |
* macros for use with parse structure |
* BEWARE: these know that the parse structure is named `p' !!! |
*/ |
#define PEEK() (*p->next) |
#define PEEK2() (*(p->next+1)) |
#define MORE() (p->next < p->end) |
#define MORE2() (p->next+1 < p->end) |
#define SEE(c) (MORE() && PEEK() == (c)) |
#define SEETWO(a, b) (MORE() && MORE2() && PEEK() == (a) && PEEK2() == (b)) |
#define EAT(c) ((SEE(c)) ? (NEXT(), 1) : 0) |
#define EATTWO(a, b) ((SEETWO(a, b)) ? (NEXT2(), 1) : 0) |
#define NEXT() (p->next++) |
#define NEXT2() (p->next += 2) |
#define NEXTn(n) (p->next += (n)) |
#define GETNEXT() (*p->next++) |
#define SETERROR(e) seterr(p, (e)) |
#define REQUIRE(co, e) ((co) || SETERROR(e)) |
#define MUSTSEE(c, e) (REQUIRE(MORE() && PEEK() == (c), e)) |
#define MUSTEAT(c, e) (REQUIRE(MORE() && GETNEXT() == (c), e)) |
#define MUSTNOTSEE(c, e) (REQUIRE(!MORE() || PEEK() != (c), e)) |
#define EMIT(op, sopnd) doemit(p, (sop)(op), (size_t)(sopnd)) |
#define INSERT(op, pos) doinsert(p, (sop)(op), HERE()-(pos)+1, pos) |
#define AHEAD(pos) dofwd(p, pos, HERE()-(pos)) |
#define ASTERN(sop, pos) EMIT(sop, HERE()-pos) |
#define HERE() (p->slen) |
#define THERE() (p->slen - 1) |
#define THERETHERE() (p->slen - 2) |
#define DROP(n) (p->slen -= (n)) |
#ifndef NDEBUG |
static int never = 0; /* for use in asserts; shuts lint up */ |
#else |
#define never 0 /* some <assert.h>s have bugs too */ |
#endif |
/* |
- regcomp - interface for parser and compilation |
= extern int regcomp(regex_t *, const char *, int); |
= #define REG_BASIC 0000 |
= #define REG_EXTENDED 0001 |
= #define REG_ICASE 0002 |
= #define REG_NOSUB 0004 |
= #define REG_NEWLINE 0010 |
= #define REG_NOSPEC 0020 |
= #define REG_PEND 0040 |
= #define REG_DUMP 0200 |
*/ |
int /* 0 success, otherwise REG_something */ |
regcomp(preg, pattern, cflags) |
regex_t *preg; |
const char *pattern; |
int cflags; |
{ |
struct parse pa; |
register struct re_guts *g; |
register struct parse *p = &pa; |
register int i; |
register size_t len; |
#ifdef REDEBUG |
# define GOODFLAGS(f) (f) |
#else |
# define GOODFLAGS(f) ((f)&~REG_DUMP) |
#endif |
cflags = GOODFLAGS(cflags); |
if ((cflags®_EXTENDED) && (cflags®_NOSPEC)) |
return(REG_INVARG); |
if (cflags®_PEND) { |
if (preg->re_endp < pattern) |
return(REG_INVARG); |
len = preg->re_endp - pattern; |
} else |
len = strlen((char *)pattern); |
/* do the mallocs early so failure handling is easy */ |
g = (struct re_guts *)malloc(sizeof(struct re_guts) + |
(NC-1)*sizeof(cat_t)); |
if (g == NULL) |
return(REG_ESPACE); |
p->ssize = len/(size_t)2*(size_t)3 + (size_t)1; /* ugh */ |
p->strip = (sop *)malloc(p->ssize * sizeof(sop)); |
p->slen = 0; |
if (p->strip == NULL) { |
free((char *)g); |
return(REG_ESPACE); |
} |
/* set things up */ |
p->g = g; |
p->next = (char *)pattern; /* convenience; we do not modify it */ |
p->end = p->next + len; |
p->error = 0; |
p->ncsalloc = 0; |
for (i = 0; i < NPAREN; i++) { |
p->pbegin[i] = 0; |
p->pend[i] = 0; |
} |
g->csetsize = NC; |
g->sets = NULL; |
g->setbits = NULL; |
g->ncsets = 0; |
g->cflags = cflags; |
g->iflags = 0; |
g->nbol = 0; |
g->neol = 0; |
g->must = NULL; |
g->mlen = 0; |
g->nsub = 0; |
g->ncategories = 1; /* category 0 is "everything else" */ |
g->categories = &g->catspace[-(CHAR_MIN)]; |
(void) memset((char *)g->catspace, 0, NC*sizeof(cat_t)); |
g->backrefs = 0; |
/* do it */ |
EMIT(OEND, 0); |
g->firststate = THERE(); |
if (cflags®_EXTENDED) |
p_ere(p, OUT); |
else if (cflags®_NOSPEC) |
p_str(p); |
else |
p_bre(p, OUT, OUT); |
EMIT(OEND, 0); |
g->laststate = THERE(); |
/* tidy up loose ends and fill things in */ |
categorize(p, g); |
stripsnug(p, g); |
findmust(p, g); |
g->nplus = pluscount(p, g); |
g->magic = MAGIC2; |
preg->re_nsub = g->nsub; |
preg->re_g = g; |
preg->re_magic = MAGIC1; |
#ifndef REDEBUG |
/* not debugging, so can't rely on the assert() in regexec() */ |
if (g->iflags&BAD) |
SETERROR(REG_ASSERT); |
#endif |
/* win or lose, we're done */ |
if (p->error != 0) /* lose */ |
regfree(preg); |
return(p->error); |
} |
/* |
- p_ere - ERE parser top level, concatenation and alternation |
== static void p_ere(register struct parse *p, int stop); |
*/ |
static void |
p_ere(p, stop) |
register struct parse *p; |
int stop; /* character this ERE should end at */ |
{ |
register char c; |
register sopno prevback; |
register sopno prevfwd; |
register sopno conc; |
register int first = 1; /* is this the first alternative? */ |
for (;;) { |
/* do a bunch of concatenated expressions */ |
conc = HERE(); |
while (MORE() && (c = PEEK()) != '|' && c != stop) |
p_ere_exp(p); |
REQUIRE(HERE() != conc, REG_EMPTY); /* require nonempty */ |
if (!EAT('|')) |
break; /* NOTE BREAK OUT */ |
if (first) { |
INSERT(OCH_, conc); /* offset is wrong */ |
prevfwd = conc; |
prevback = conc; |
first = 0; |
} |
ASTERN(OOR1, prevback); |
prevback = THERE(); |
AHEAD(prevfwd); /* fix previous offset */ |
prevfwd = HERE(); |
EMIT(OOR2, 0); /* offset is very wrong */ |
} |
if (!first) { /* tail-end fixups */ |
AHEAD(prevfwd); |
ASTERN(O_CH, prevback); |
} |
assert(!MORE() || SEE(stop)); |
} |
/* |
- p_ere_exp - parse one subERE, an atom possibly followed by a repetition op |
== static void p_ere_exp(register struct parse *p); |
*/ |
static void |
p_ere_exp(p) |
register struct parse *p; |
{ |
register char c; |
register sopno pos; |
register int count; |
register int count2; |
register sopno subno; |
int wascaret = 0; |
assert(MORE()); /* caller should have ensured this */ |
c = GETNEXT(); |
pos = HERE(); |
switch (c) { |
case '(': |
REQUIRE(MORE(), REG_EPAREN); |
p->g->nsub++; |
subno = p->g->nsub; |
if (subno < NPAREN) |
p->pbegin[subno] = HERE(); |
EMIT(OLPAREN, subno); |
if (!SEE(')')) |
p_ere(p, ')'); |
if (subno < NPAREN) { |
p->pend[subno] = HERE(); |
assert(p->pend[subno] != 0); |
} |
EMIT(ORPAREN, subno); |
MUSTEAT(')', REG_EPAREN); |
break; |
#ifndef POSIX_MISTAKE |
case ')': /* happens only if no current unmatched ( */ |
/* |
* You may ask, why the ifndef? Because I didn't notice |
* this until slightly too late for 1003.2, and none of the |
* other 1003.2 regular-expression reviewers noticed it at |
* all. So an unmatched ) is legal POSIX, at least until |
* we can get it fixed. |
*/ |
SETERROR(REG_EPAREN); |
break; |
#endif |
case '^': |
EMIT(OBOL, 0); |
p->g->iflags |= USEBOL; |
p->g->nbol++; |
wascaret = 1; |
break; |
case '$': |
EMIT(OEOL, 0); |
p->g->iflags |= USEEOL; |
p->g->neol++; |
break; |
case '|': |
SETERROR(REG_EMPTY); |
break; |
case '*': |
case '+': |
case '?': |
SETERROR(REG_BADRPT); |
break; |
case '.': |
if (p->g->cflags®_NEWLINE) |
nonnewline(p); |
else |
EMIT(OANY, 0); |
break; |
case '[': |
p_bracket(p); |
break; |
case '\\': |
REQUIRE(MORE(), REG_EESCAPE); |
c = GETNEXT(); |
ordinary(p, c); |
break; |
case '{': /* okay as ordinary except if digit follows */ |
REQUIRE(!MORE() || !isdigit(PEEK()), REG_BADRPT); |
/* FALLTHROUGH */ |
default: |
ordinary(p, c); |
break; |
} |
if (!MORE()) |
return; |
c = PEEK(); |
/* we call { a repetition if followed by a digit */ |
if (!( c == '*' || c == '+' || c == '?' || |
(c == '{' && MORE2() && isdigit(PEEK2())) )) |
return; /* no repetition, we're done */ |
NEXT(); |
REQUIRE(!wascaret, REG_BADRPT); |
switch (c) { |
case '*': /* implemented as +? */ |
/* this case does not require the (y|) trick, noKLUDGE */ |
INSERT(OPLUS_, pos); |
ASTERN(O_PLUS, pos); |
INSERT(OQUEST_, pos); |
ASTERN(O_QUEST, pos); |
break; |
case '+': |
INSERT(OPLUS_, pos); |
ASTERN(O_PLUS, pos); |
break; |
case '?': |
/* KLUDGE: emit y? as (y|) until subtle bug gets fixed */ |
INSERT(OCH_, pos); /* offset slightly wrong */ |
ASTERN(OOR1, pos); /* this one's right */ |
AHEAD(pos); /* fix the OCH_ */ |
EMIT(OOR2, 0); /* offset very wrong... */ |
AHEAD(THERE()); /* ...so fix it */ |
ASTERN(O_CH, THERETHERE()); |
break; |
case '{': |
count = p_count(p); |
if (EAT(',')) { |
if (isdigit(PEEK())) { |
count2 = p_count(p); |
REQUIRE(count <= count2, REG_BADBR); |
} else /* single number with comma */ |
count2 = INFINITY; |
} else /* just a single number */ |
count2 = count; |
repeat(p, pos, count, count2); |
if (!EAT('}')) { /* error heuristics */ |
while (MORE() && PEEK() != '}') |
NEXT(); |
REQUIRE(MORE(), REG_EBRACE); |
SETERROR(REG_BADBR); |
} |
break; |
} |
if (!MORE()) |
return; |
c = PEEK(); |
if (!( c == '*' || c == '+' || c == '?' || |
(c == '{' && MORE2() && isdigit(PEEK2())) ) ) |
return; |
SETERROR(REG_BADRPT); |
} |
/* |
- p_str - string (no metacharacters) "parser" |
== static void p_str(register struct parse *p); |
*/ |
static void |
p_str(p) |
register struct parse *p; |
{ |
REQUIRE(MORE(), REG_EMPTY); |
while (MORE()) |
ordinary(p, GETNEXT()); |
} |
/* |
- p_bre - BRE parser top level, anchoring and concatenation |
== static void p_bre(register struct parse *p, register int end1, \ |
== register int end2); |
* Giving end1 as OUT essentially eliminates the end1/end2 check. |
* |
* This implementation is a bit of a kludge, in that a trailing $ is first |
* taken as an ordinary character and then revised to be an anchor. The |
* only undesirable side effect is that '$' gets included as a character |
* category in such cases. This is fairly harmless; not worth fixing. |
* The amount of lookahead needed to avoid this kludge is excessive. |
*/ |
static void |
p_bre(p, end1, end2) |
register struct parse *p; |
register int end1; /* first terminating character */ |
register int end2; /* second terminating character */ |
{ |
register sopno start = HERE(); |
register int first = 1; /* first subexpression? */ |
register int wasdollar = 0; |
if (EAT('^')) { |
EMIT(OBOL, 0); |
p->g->iflags |= USEBOL; |
p->g->nbol++; |
} |
while (MORE() && !SEETWO(end1, end2)) { |
wasdollar = p_simp_re(p, first); |
first = 0; |
} |
if (wasdollar) { /* oops, that was a trailing anchor */ |
DROP(1); |
EMIT(OEOL, 0); |
p->g->iflags |= USEEOL; |
p->g->neol++; |
} |
REQUIRE(HERE() != start, REG_EMPTY); /* require nonempty */ |
} |
/* |
- p_simp_re - parse a simple RE, an atom possibly followed by a repetition |
== static int p_simp_re(register struct parse *p, int starordinary); |
*/ |
static int /* was the simple RE an unbackslashed $? */ |
p_simp_re(p, starordinary) |
register struct parse *p; |
int starordinary; /* is a leading * an ordinary character? */ |
{ |
register int c; |
register int count; |
register int count2; |
register sopno pos; |
register int i; |
register sopno subno; |
# define BACKSL (1<<CHAR_BIT) |
pos = HERE(); /* repetion op, if any, covers from here */ |
assert(MORE()); /* caller should have ensured this */ |
c = GETNEXT(); |
if (c == '\\') { |
REQUIRE(MORE(), REG_EESCAPE); |
c = BACKSL | (unsigned char)GETNEXT(); |
} |
switch (c) { |
case '.': |
if (p->g->cflags®_NEWLINE) |
nonnewline(p); |
else |
EMIT(OANY, 0); |
break; |
case '[': |
p_bracket(p); |
break; |
case BACKSL|'{': |
SETERROR(REG_BADRPT); |
break; |
case BACKSL|'(': |
p->g->nsub++; |
subno = p->g->nsub; |
if (subno < NPAREN) |
p->pbegin[subno] = HERE(); |
EMIT(OLPAREN, subno); |
/* the MORE here is an error heuristic */ |
if (MORE() && !SEETWO('\\', ')')) |
p_bre(p, '\\', ')'); |
if (subno < NPAREN) { |
p->pend[subno] = HERE(); |
assert(p->pend[subno] != 0); |
} |
EMIT(ORPAREN, subno); |
REQUIRE(EATTWO('\\', ')'), REG_EPAREN); |
break; |
case BACKSL|')': /* should not get here -- must be user */ |
case BACKSL|'}': |
SETERROR(REG_EPAREN); |
break; |
case BACKSL|'1': |
case BACKSL|'2': |
case BACKSL|'3': |
case BACKSL|'4': |
case BACKSL|'5': |
case BACKSL|'6': |
case BACKSL|'7': |
case BACKSL|'8': |
case BACKSL|'9': |
i = (c&~BACKSL) - '0'; |
assert(i < NPAREN); |
if (p->pend[i] != 0) { |
assert(i <= p->g->nsub); |
EMIT(OBACK_, i); |
assert(p->pbegin[i] != 0); |
assert(OP(p->strip[p->pbegin[i]]) == OLPAREN); |
assert(OP(p->strip[p->pend[i]]) == ORPAREN); |
(void) dupl(p, p->pbegin[i]+1, p->pend[i]); |
EMIT(O_BACK, i); |
} else |
SETERROR(REG_ESUBREG); |
p->g->backrefs = 1; |
break; |
case '*': |
REQUIRE(starordinary, REG_BADRPT); |
/* FALLTHROUGH */ |
default: |
ordinary(p, c &~ BACKSL); |
break; |
} |
if (EAT('*')) { /* implemented as +? */ |
/* this case does not require the (y|) trick, noKLUDGE */ |
INSERT(OPLUS_, pos); |
ASTERN(O_PLUS, pos); |
INSERT(OQUEST_, pos); |
ASTERN(O_QUEST, pos); |
} else if (EATTWO('\\', '{')) { |
count = p_count(p); |
if (EAT(',')) { |
if (MORE() && isdigit(PEEK())) { |
count2 = p_count(p); |
REQUIRE(count <= count2, REG_BADBR); |
} else /* single number with comma */ |
count2 = INFINITY; |
} else /* just a single number */ |
count2 = count; |
repeat(p, pos, count, count2); |
if (!EATTWO('\\', '}')) { /* error heuristics */ |
while (MORE() && !SEETWO('\\', '}')) |
NEXT(); |
REQUIRE(MORE(), REG_EBRACE); |
SETERROR(REG_BADBR); |
} |
} else if (c == (unsigned char)'$') /* $ (but not \$) ends it */ |
return(1); |
return(0); |
} |
/* |
- p_count - parse a repetition count |
== static int p_count(register struct parse *p); |
*/ |
static int /* the value */ |
p_count(p) |
register struct parse *p; |
{ |
register int count = 0; |
register int ndigits = 0; |
while (MORE() && isdigit(PEEK()) && count <= DUPMAX) { |
count = count*10 + (GETNEXT() - '0'); |
ndigits++; |
} |
REQUIRE(ndigits > 0 && count <= DUPMAX, REG_BADBR); |
return(count); |
} |
/* |
- p_bracket - parse a bracketed character list |
== static void p_bracket(register struct parse *p); |
* |
* Note a significant property of this code: if the allocset() did SETERROR, |
* no set operations are done. |
*/ |
static void |
p_bracket(p) |
register struct parse *p; |
{ |
register char c; |
register cset *cs = allocset(p); |
register int invert = 0; |
/* Dept of Truly Sickening Special-Case Kludges */ |
if (p->next + 5 < p->end && strncmp(p->next, "[:<:]]", 6) == 0) { |
EMIT(OBOW, 0); |
NEXTn(6); |
return; |
} |
if (p->next + 5 < p->end && strncmp(p->next, "[:>:]]", 6) == 0) { |
EMIT(OEOW, 0); |
NEXTn(6); |
return; |
} |
if (EAT('^')) |
invert++; /* make note to invert set at end */ |
if (EAT(']')) |
CHadd(cs, ']'); |
else if (EAT('-')) |
CHadd(cs, '-'); |
while (MORE() && PEEK() != ']' && !SEETWO('-', ']')) |
p_b_term(p, cs); |
if (EAT('-')) |
CHadd(cs, '-'); |
MUSTEAT(']', REG_EBRACK); |
if (p->error != 0) /* don't mess things up further */ |
return; |
if (p->g->cflags®_ICASE) { |
register int i; |
register int ci; |
for (i = p->g->csetsize - 1; i >= 0; i--) |
if (CHIN(cs, i) && isalpha(i)) { |
ci = othercase(i); |
if (ci != i) |
CHadd(cs, ci); |
} |
if (cs->multis != NULL) |
mccase(p, cs); |
} |
if (invert) { |
register int i; |
for (i = p->g->csetsize - 1; i >= 0; i--) |
if (CHIN(cs, i)) |
CHsub(cs, i); |
else |
CHadd(cs, i); |
if (p->g->cflags®_NEWLINE) |
CHsub(cs, '\n'); |
if (cs->multis != NULL) |
mcinvert(p, cs); |
} |
assert(cs->multis == NULL); /* xxx */ |
if (nch(p, cs) == 1) { /* optimize singleton sets */ |
ordinary(p, firstch(p, cs)); |
freeset(p, cs); |
} else |
EMIT(OANYOF, freezeset(p, cs)); |
} |
/* |
- p_b_term - parse one term of a bracketed character list |
== static void p_b_term(register struct parse *p, register cset *cs); |
*/ |
static void |
p_b_term(p, cs) |
register struct parse *p; |
register cset *cs; |
{ |
register char c; |
register char start, finish; |
register int i; |
/* classify what we've got */ |
switch ((MORE()) ? PEEK() : '\0') { |
case '[': |
c = (MORE2()) ? PEEK2() : '\0'; |
break; |
case '-': |
SETERROR(REG_ERANGE); |
return; /* NOTE RETURN */ |
break; |
default: |
c = '\0'; |
break; |
} |
switch (c) { |
case ':': /* character class */ |
NEXT2(); |
REQUIRE(MORE(), REG_EBRACK); |
c = PEEK(); |
REQUIRE(c != '-' && c != ']', REG_ECTYPE); |
p_b_cclass(p, cs); |
REQUIRE(MORE(), REG_EBRACK); |
REQUIRE(EATTWO(':', ']'), REG_ECTYPE); |
break; |
case '=': /* equivalence class */ |
NEXT2(); |
REQUIRE(MORE(), REG_EBRACK); |
c = PEEK(); |
REQUIRE(c != '-' && c != ']', REG_ECOLLATE); |
p_b_eclass(p, cs); |
REQUIRE(MORE(), REG_EBRACK); |
REQUIRE(EATTWO('=', ']'), REG_ECOLLATE); |
break; |
default: /* symbol, ordinary character, or range */ |
/* xxx revision needed for multichar stuff */ |
start = p_b_symbol(p); |
if (SEE('-') && MORE2() && PEEK2() != ']') { |
/* range */ |
NEXT(); |
if (EAT('-')) |
finish = '-'; |
else |
finish = p_b_symbol(p); |
} else |
finish = start; |
/* xxx what about signed chars here... */ |
REQUIRE(start <= finish, REG_ERANGE); |
for (i = start; i <= finish; i++) |
CHadd(cs, i); |
break; |
} |
} |
/* |
- p_b_cclass - parse a character-class name and deal with it |
== static void p_b_cclass(register struct parse *p, register cset *cs); |
*/ |
static void |
p_b_cclass(p, cs) |
register struct parse *p; |
register cset *cs; |
{ |
register char *sp = p->next; |
register struct cclass *cp; |
register size_t len; |
register char *u; |
register char c; |
while (MORE() && isalpha(PEEK())) |
NEXT(); |
len = p->next - sp; |
for (cp = cclasses; cp->name != NULL; cp++) |
if (strncmp(cp->name, sp, len) == 0 && cp->name[len] == '\0') |
break; |
if (cp->name == NULL) { |
/* oops, didn't find it */ |
SETERROR(REG_ECTYPE); |
return; |
} |
u = cp->chars; |
while ((c = *u++) != '\0') |
CHadd(cs, c); |
for (u = cp->multis; *u != '\0'; u += strlen(u) + 1) |
MCadd(p, cs, u); |
} |
/* |
- p_b_eclass - parse an equivalence-class name and deal with it |
== static void p_b_eclass(register struct parse *p, register cset *cs); |
* |
* This implementation is incomplete. xxx |
*/ |
static void |
p_b_eclass(p, cs) |
register struct parse *p; |
register cset *cs; |
{ |
register char c; |
c = p_b_coll_elem(p, '='); |
CHadd(cs, c); |
} |
/* |
- p_b_symbol - parse a character or [..]ed multicharacter collating symbol |
== static char p_b_symbol(register struct parse *p); |
*/ |
static char /* value of symbol */ |
p_b_symbol(p) |
register struct parse *p; |
{ |
register char value; |
REQUIRE(MORE(), REG_EBRACK); |
if (!EATTWO('[', '.')) |
return(GETNEXT()); |
/* collating symbol */ |
value = p_b_coll_elem(p, '.'); |
REQUIRE(EATTWO('.', ']'), REG_ECOLLATE); |
return(value); |
} |
/* |
- p_b_coll_elem - parse a collating-element name and look it up |
== static char p_b_coll_elem(register struct parse *p, int endc); |
*/ |
static char /* value of collating element */ |
p_b_coll_elem(p, endc) |
register struct parse *p; |
int endc; /* name ended by endc,']' */ |
{ |
register char *sp = p->next; |
register struct cname *cp; |
register int len; |
register char c; |
while (MORE() && !SEETWO(endc, ']')) |
NEXT(); |
if (!MORE()) { |
SETERROR(REG_EBRACK); |
return(0); |
} |
len = p->next - sp; |
for (cp = cnames; cp->name != NULL; cp++) |
if (strncmp(cp->name, sp, len) == 0 && cp->name[len] == '\0') |
return(cp->code); /* known name */ |
if (len == 1) |
return(*sp); /* single character */ |
SETERROR(REG_ECOLLATE); /* neither */ |
return(0); |
} |
/* |
- othercase - return the case counterpart of an alphabetic |
== static char othercase(int ch); |
*/ |
static char /* if no counterpart, return ch */ |
othercase(ch) |
int ch; |
{ |
assert(isalpha(ch)); |
if (isupper(ch)) |
return(tolower(ch)); |
else if (islower(ch)) |
return(toupper(ch)); |
else /* peculiar, but could happen */ |
return(ch); |
} |
/* |
- bothcases - emit a dualcase version of a two-case character |
== static void bothcases(register struct parse *p, int ch); |
* |
* Boy, is this implementation ever a kludge... |
*/ |
static void |
bothcases(p, ch) |
register struct parse *p; |
int ch; |
{ |
register char *oldnext = p->next; |
register char *oldend = p->end; |
char bracket[3]; |
assert(othercase(ch) != ch); /* p_bracket() would recurse */ |
p->next = bracket; |
p->end = bracket+2; |
bracket[0] = ch; |
bracket[1] = ']'; |
bracket[2] = '\0'; |
p_bracket(p); |
assert(p->next == bracket+2); |
p->next = oldnext; |
p->end = oldend; |
} |
/* |
- ordinary - emit an ordinary character |
== static void ordinary(register struct parse *p, register int ch); |
*/ |
static void |
ordinary(p, ch) |
register struct parse *p; |
register int ch; |
{ |
register cat_t *cap = p->g->categories; |
if ((p->g->cflags®_ICASE) && isalpha(ch) && othercase(ch) != ch) |
bothcases(p, ch); |
else { |
EMIT(OCHAR, (unsigned char)ch); |
if (cap[ch] == 0) |
cap[ch] = p->g->ncategories++; |
} |
} |
/* |
- nonnewline - emit REG_NEWLINE version of OANY |
== static void nonnewline(register struct parse *p); |
* |
* Boy, is this implementation ever a kludge... |
*/ |
static void |
nonnewline(p) |
register struct parse *p; |
{ |
register char *oldnext = p->next; |
register char *oldend = p->end; |
char bracket[4]; |
p->next = bracket; |
p->end = bracket+3; |
bracket[0] = '^'; |
bracket[1] = '\n'; |
bracket[2] = ']'; |
bracket[3] = '\0'; |
p_bracket(p); |
assert(p->next == bracket+3); |
p->next = oldnext; |
p->end = oldend; |
} |
/* |
- repeat - generate code for a bounded repetition, recursively if needed |
== static void repeat(register struct parse *p, sopno start, int from, int to); |
*/ |
static void |
repeat(p, start, from, to) |
register struct parse *p; |
sopno start; /* operand from here to end of strip */ |
int from; /* repeated from this number */ |
int to; /* to this number of times (maybe INFINITY) */ |
{ |
register sopno finish = HERE(); |
# define N 2 |
# define INF 3 |
# define REP(f, t) ((f)*8 + (t)) |
# define MAP(n) (((n) <= 1) ? (n) : ((n) == INFINITY) ? INF : N) |
register sopno copy; |
if (p->error != 0) /* head off possible runaway recursion */ |
return; |
assert(from <= to); |
switch (REP(MAP(from), MAP(to))) { |
case REP(0, 0): /* must be user doing this */ |
DROP(finish-start); /* drop the operand */ |
break; |
case REP(0, 1): /* as x{1,1}? */ |
case REP(0, N): /* as x{1,n}? */ |
case REP(0, INF): /* as x{1,}? */ |
/* KLUDGE: emit y? as (y|) until subtle bug gets fixed */ |
INSERT(OCH_, start); /* offset is wrong... */ |
repeat(p, start+1, 1, to); |
ASTERN(OOR1, start); |
AHEAD(start); /* ... fix it */ |
EMIT(OOR2, 0); |
AHEAD(THERE()); |
ASTERN(O_CH, THERETHERE()); |
break; |
case REP(1, 1): /* trivial case */ |
/* done */ |
break; |
case REP(1, N): /* as x?x{1,n-1} */ |
/* KLUDGE: emit y? as (y|) until subtle bug gets fixed */ |
INSERT(OCH_, start); |
ASTERN(OOR1, start); |
AHEAD(start); |
EMIT(OOR2, 0); /* offset very wrong... */ |
AHEAD(THERE()); /* ...so fix it */ |
ASTERN(O_CH, THERETHERE()); |
copy = dupl(p, start+1, finish+1); |
assert(copy == finish+4); |
repeat(p, copy, 1, to-1); |
break; |
case REP(1, INF): /* as x+ */ |
INSERT(OPLUS_, start); |
ASTERN(O_PLUS, start); |
break; |
case REP(N, N): /* as xx{m-1,n-1} */ |
copy = dupl(p, start, finish); |
repeat(p, copy, from-1, to-1); |
break; |
case REP(N, INF): /* as xx{n-1,INF} */ |
copy = dupl(p, start, finish); |
repeat(p, copy, from-1, to); |
break; |
default: /* "can't happen" */ |
SETERROR(REG_ASSERT); /* just in case */ |
break; |
} |
} |
/* |
- seterr - set an error condition |
== static int seterr(register struct parse *p, int e); |
*/ |
static int /* useless but makes type checking happy */ |
seterr(p, e) |
register struct parse *p; |
int e; |
{ |
if (p->error == 0) /* keep earliest error condition */ |
p->error = e; |
p->next = nuls; /* try to bring things to a halt */ |
p->end = nuls; |
return(0); /* make the return value well-defined */ |
} |
/* |
- allocset - allocate a set of characters for [] |
== static cset *allocset(register struct parse *p); |
*/ |
static cset * |
allocset(p) |
register struct parse *p; |
{ |
register int no = p->g->ncsets++; |
register size_t nc; |
register size_t nbytes; |
register cset *cs; |
register size_t css = (size_t)p->g->csetsize; |
register int i; |
if (no >= p->ncsalloc) { /* need another column of space */ |
p->ncsalloc += CHAR_BIT; |
nc = p->ncsalloc; |
assert(nc % CHAR_BIT == 0); |
nbytes = nc / CHAR_BIT * css; |
if (p->g->sets == NULL) |
p->g->sets = (cset *)malloc(nc * sizeof(cset)); |
else |
p->g->sets = (cset *)realloc((char *)p->g->sets, |
nc * sizeof(cset)); |
if (p->g->setbits == NULL) |
p->g->setbits = (uch *)malloc(nbytes); |
else { |
p->g->setbits = (uch *)realloc((char *)p->g->setbits, |
nbytes); |
/* xxx this isn't right if setbits is now NULL */ |
for (i = 0; i < no; i++) |
p->g->sets[i].ptr = p->g->setbits + css*(i/CHAR_BIT); |
} |
if (p->g->sets != NULL && p->g->setbits != NULL) |
(void) memset((char *)p->g->setbits + (nbytes - css), |
0, css); |
else { |
no = 0; |
SETERROR(REG_ESPACE); |
/* caller's responsibility not to do set ops */ |
} |
} |
assert(p->g->sets != NULL); /* xxx */ |
cs = &p->g->sets[no]; |
cs->ptr = p->g->setbits + css*((no)/CHAR_BIT); |
cs->mask = 1 << ((no) % CHAR_BIT); |
cs->hash = 0; |
cs->smultis = 0; |
cs->multis = NULL; |
return(cs); |
} |
/* |
- freeset - free a now-unused set |
== static void freeset(register struct parse *p, register cset *cs); |
*/ |
static void |
freeset(p, cs) |
register struct parse *p; |
register cset *cs; |
{ |
register int i; |
register cset *top = &p->g->sets[p->g->ncsets]; |
register size_t css = (size_t)p->g->csetsize; |
for (i = 0; i < css; i++) |
CHsub(cs, i); |
if (cs == top-1) /* recover only the easy case */ |
p->g->ncsets--; |
} |
/* |
- freezeset - final processing on a set of characters |
== static int freezeset(register struct parse *p, register cset *cs); |
* |
* The main task here is merging identical sets. This is usually a waste |
* of time (although the hash code minimizes the overhead), but can win |
* big if REG_ICASE is being used. REG_ICASE, by the way, is why the hash |
* is done using addition rather than xor -- all ASCII [aA] sets xor to |
* the same value! |
*/ |
static int /* set number */ |
freezeset(p, cs) |
register struct parse *p; |
register cset *cs; |
{ |
register uch h = cs->hash; |
register int i; |
register cset *top = &p->g->sets[p->g->ncsets]; |
register cset *cs2; |
register size_t css = (size_t)p->g->csetsize; |
/* look for an earlier one which is the same */ |
for (cs2 = &p->g->sets[0]; cs2 < top; cs2++) |
if (cs2->hash == h && cs2 != cs) { |
/* maybe */ |
for (i = 0; i < css; i++) |
if (!!CHIN(cs2, i) != !!CHIN(cs, i)) |
break; /* no */ |
if (i == css) |
break; /* yes */ |
} |
if (cs2 < top) { /* found one */ |
freeset(p, cs); |
cs = cs2; |
} |
return((int)(cs - p->g->sets)); |
} |
/* |
- firstch - return first character in a set (which must have at least one) |
== static int firstch(register struct parse *p, register cset *cs); |
*/ |
static int /* character; there is no "none" value */ |
firstch(p, cs) |
register struct parse *p; |
register cset *cs; |
{ |
register int i; |
register size_t css = (size_t)p->g->csetsize; |
for (i = 0; i < css; i++) |
if (CHIN(cs, i)) |
return((char)i); |
assert(never); |
return(0); /* arbitrary */ |
} |
/* |
- nch - number of characters in a set |
== static int nch(register struct parse *p, register cset *cs); |
*/ |
static int |
nch(p, cs) |
register struct parse *p; |
register cset *cs; |
{ |
register int i; |
register size_t css = (size_t)p->g->csetsize; |
register int n = 0; |
for (i = 0; i < css; i++) |
if (CHIN(cs, i)) |
n++; |
return(n); |
} |
/* |
- mcadd - add a collating element to a cset |
== static void mcadd(register struct parse *p, register cset *cs, \ |
== register char *cp); |
*/ |
static void |
mcadd(p, cs, cp) |
register struct parse *p; |
register cset *cs; |
register char *cp; |
{ |
register size_t oldend = cs->smultis; |
cs->smultis += strlen(cp) + 1; |
if (cs->multis == NULL) |
cs->multis = malloc(cs->smultis); |
else |
cs->multis = realloc(cs->multis, cs->smultis); |
if (cs->multis == NULL) { |
SETERROR(REG_ESPACE); |
return; |
} |
(void) strcpy(cs->multis + oldend - 1, cp); |
cs->multis[cs->smultis - 1] = '\0'; |
} |
/* |
- mcsub - subtract a collating element from a cset |
== static void mcsub(register cset *cs, register char *cp); |
*/ |
static void |
mcsub(cs, cp) |
register cset *cs; |
register char *cp; |
{ |
register char *fp = mcfind(cs, cp); |
register size_t len = strlen(fp); |
assert(fp != NULL); |
(void) memmove(fp, fp + len + 1, |
cs->smultis - (fp + len + 1 - cs->multis)); |
cs->smultis -= len; |
if (cs->smultis == 0) { |
free(cs->multis); |
cs->multis = NULL; |
return; |
} |
cs->multis = realloc(cs->multis, cs->smultis); |
assert(cs->multis != NULL); |
} |
/* |
- mcin - is a collating element in a cset? |
== static int mcin(register cset *cs, register char *cp); |
*/ |
static int |
mcin(cs, cp) |
register cset *cs; |
register char *cp; |
{ |
return(mcfind(cs, cp) != NULL); |
} |
/* |
- mcfind - find a collating element in a cset |
== static char *mcfind(register cset *cs, register char *cp); |
*/ |
static char * |
mcfind(cs, cp) |
register cset *cs; |
register char *cp; |
{ |
register char *p; |
if (cs->multis == NULL) |
return(NULL); |
for (p = cs->multis; *p != '\0'; p += strlen(p) + 1) |
if (strcmp(cp, p) == 0) |
return(p); |
return(NULL); |
} |
/* |
- mcinvert - invert the list of collating elements in a cset |
== static void mcinvert(register struct parse *p, register cset *cs); |
* |
* This would have to know the set of possibilities. Implementation |
* is deferred. |
*/ |
static void |
mcinvert(p, cs) |
register struct parse *p; |
register cset *cs; |
{ |
assert(cs->multis == NULL); /* xxx */ |
} |
/* |
- mccase - add case counterparts of the list of collating elements in a cset |
== static void mccase(register struct parse *p, register cset *cs); |
* |
* This would have to know the set of possibilities. Implementation |
* is deferred. |
*/ |
static void |
mccase(p, cs) |
register struct parse *p; |
register cset *cs; |
{ |
assert(cs->multis == NULL); /* xxx */ |
} |
/* |
- isinsets - is this character in any sets? |
== static int isinsets(register struct re_guts *g, int c); |
*/ |
static int /* predicate */ |
isinsets(g, c) |
register struct re_guts *g; |
int c; |
{ |
register uch *col; |
register int i; |
register int ncols = (g->ncsets+(CHAR_BIT-1)) / CHAR_BIT; |
register unsigned uc = (unsigned char)c; |
for (i = 0, col = g->setbits; i < ncols; i++, col += g->csetsize) |
if (col[uc] != 0) |
return(1); |
return(0); |
} |
/* |
- samesets - are these two characters in exactly the same sets? |
== static int samesets(register struct re_guts *g, int c1, int c2); |
*/ |
static int /* predicate */ |
samesets(g, c1, c2) |
register struct re_guts *g; |
int c1; |
int c2; |
{ |
register uch *col; |
register int i; |
register int ncols = (g->ncsets+(CHAR_BIT-1)) / CHAR_BIT; |
register unsigned uc1 = (unsigned char)c1; |
register unsigned uc2 = (unsigned char)c2; |
for (i = 0, col = g->setbits; i < ncols; i++, col += g->csetsize) |
if (col[uc1] != col[uc2]) |
return(0); |
return(1); |
} |
/* |
- categorize - sort out character categories |
== static void categorize(struct parse *p, register struct re_guts *g); |
*/ |
static void |
categorize(p, g) |
struct parse *p; |
register struct re_guts *g; |
{ |
register cat_t *cats = g->categories; |
register int c; |
register int c2; |
register cat_t cat; |
/* avoid making error situations worse */ |
if (p->error != 0) |
return; |
for (c = CHAR_MIN; c <= CHAR_MAX; c++) |
if (cats[c] == 0 && isinsets(g, c)) { |
cat = g->ncategories++; |
cats[c] = cat; |
for (c2 = c+1; c2 <= CHAR_MAX; c2++) |
if (cats[c2] == 0 && samesets(g, c, c2)) |
cats[c2] = cat; |
} |
} |
/* |
- dupl - emit a duplicate of a bunch of sops |
== static sopno dupl(register struct parse *p, sopno start, sopno finish); |
*/ |
static sopno /* start of duplicate */ |
dupl(p, start, finish) |
register struct parse *p; |
sopno start; /* from here */ |
sopno finish; /* to this less one */ |
{ |
register sopno ret = HERE(); |
register sopno len = finish - start; |
assert(finish >= start); |
if (len == 0) |
return(ret); |
enlarge(p, p->ssize + len); /* this many unexpected additions */ |
assert(p->ssize >= p->slen + len); |
(void) memcpy((char *)(p->strip + p->slen), |
(char *)(p->strip + start), (size_t)len*sizeof(sop)); |
p->slen += len; |
return(ret); |
} |
/* |
- doemit - emit a strip operator |
== static void doemit(register struct parse *p, sop op, size_t opnd); |
* |
* It might seem better to implement this as a macro with a function as |
* hard-case backup, but it's just too big and messy unless there are |
* some changes to the data structures. Maybe later. |
*/ |
static void |
doemit(p, op, opnd) |
register struct parse *p; |
sop op; |
size_t opnd; |
{ |
/* avoid making error situations worse */ |
if (p->error != 0) |
return; |
/* deal with oversize operands ("can't happen", more or less) */ |
assert(opnd < 1<<OPSHIFT); |
/* deal with undersized strip */ |
if (p->slen >= p->ssize) |
enlarge(p, (p->ssize+1) / 2 * 3); /* +50% */ |
assert(p->slen < p->ssize); |
/* finally, it's all reduced to the easy case */ |
p->strip[p->slen++] = SOP(op, opnd); |
} |
/* |
- doinsert - insert a sop into the strip |
== static void doinsert(register struct parse *p, sop op, size_t opnd, sopno pos); |
*/ |
static void |
doinsert(p, op, opnd, pos) |
register struct parse *p; |
sop op; |
size_t opnd; |
sopno pos; |
{ |
register sopno sn; |
register sop s; |
register int i; |
/* avoid making error situations worse */ |
if (p->error != 0) |
return; |
sn = HERE(); |
EMIT(op, opnd); /* do checks, ensure space */ |
assert(HERE() == sn+1); |
s = p->strip[sn]; |
/* adjust paren pointers */ |
assert(pos > 0); |
for (i = 1; i < NPAREN; i++) { |
if (p->pbegin[i] >= pos) { |
p->pbegin[i]++; |
} |
if (p->pend[i] >= pos) { |
p->pend[i]++; |
} |
} |
memmove((char *)&p->strip[pos+1], (char *)&p->strip[pos], |
(HERE()-pos-1)*sizeof(sop)); |
p->strip[pos] = s; |
} |
/* |
- dofwd - complete a forward reference |
== static void dofwd(register struct parse *p, sopno pos, sop value); |
*/ |
static void |
dofwd(p, pos, value) |
register struct parse *p; |
register sopno pos; |
sop value; |
{ |
/* avoid making error situations worse */ |
if (p->error != 0) |
return; |
assert(value < 1<<OPSHIFT); |
p->strip[pos] = OP(p->strip[pos]) | value; |
} |
/* |
- enlarge - enlarge the strip |
== static void enlarge(register struct parse *p, sopno size); |
*/ |
static void |
enlarge(p, size) |
register struct parse *p; |
register sopno size; |
{ |
register sop *sp; |
if (p->ssize >= size) |
return; |
sp = (sop *)realloc(p->strip, size*sizeof(sop)); |
if (sp == NULL) { |
SETERROR(REG_ESPACE); |
return; |
} |
p->strip = sp; |
p->ssize = size; |
} |
/* |
- stripsnug - compact the strip |
== static void stripsnug(register struct parse *p, register struct re_guts *g); |
*/ |
static void |
stripsnug(p, g) |
register struct parse *p; |
register struct re_guts *g; |
{ |
g->nstates = p->slen; |
g->strip = (sop *)realloc((char *)p->strip, p->slen * sizeof(sop)); |
if (g->strip == NULL) { |
SETERROR(REG_ESPACE); |
g->strip = p->strip; |
} |
} |
/* |
- findmust - fill in must and mlen with longest mandatory literal string |
== static void findmust(register struct parse *p, register struct re_guts *g); |
* |
* This algorithm could do fancy things like analyzing the operands of | |
* for common subsequences. Someday. This code is simple and finds most |
* of the interesting cases. |
* |
* Note that must and mlen got initialized during setup. |
*/ |
static void |
findmust(p, g) |
struct parse *p; |
register struct re_guts *g; |
{ |
register sop *scan; |
sop *start; |
register sop *newstart; |
register sopno newlen; |
register sop s; |
register char *cp; |
register sopno i; |
/* avoid making error situations worse */ |
if (p->error != 0) |
return; |
/* find the longest OCHAR sequence in strip */ |
newlen = 0; |
scan = g->strip + 1; |
do { |
s = *scan++; |
switch (OP(s)) { |
case OCHAR: /* sequence member */ |
if (newlen == 0) /* new sequence */ |
newstart = scan - 1; |
newlen++; |
break; |
case OPLUS_: /* things that don't break one */ |
case OLPAREN: |
case ORPAREN: |
break; |
case OQUEST_: /* things that must be skipped */ |
case OCH_: |
scan--; |
do { |
scan += OPND(s); |
s = *scan; |
/* assert() interferes w debug printouts */ |
if (OP(s) != O_QUEST && OP(s) != O_CH && |
OP(s) != OOR2) { |
g->iflags |= BAD; |
return; |
} |
} while (OP(s) != O_QUEST && OP(s) != O_CH); |
/* fallthrough */ |
default: /* things that break a sequence */ |
if (newlen > g->mlen) { /* ends one */ |
start = newstart; |
g->mlen = newlen; |
} |
newlen = 0; |
break; |
} |
} while (OP(s) != OEND); |
if (g->mlen == 0) /* there isn't one */ |
return; |
/* turn it into a character string */ |
g->must = malloc((size_t)g->mlen + 1); |
if (g->must == NULL) { /* argh; just forget it */ |
g->mlen = 0; |
return; |
} |
cp = g->must; |
scan = start; |
for (i = g->mlen; i > 0; i--) { |
while (OP(s = *scan++) != OCHAR) |
continue; |
assert(cp < g->must + g->mlen); |
*cp++ = (char)OPND(s); |
} |
assert(cp == g->must + g->mlen); |
*cp++ = '\0'; /* just on general principles */ |
} |
/* |
- pluscount - count + nesting |
== static sopno pluscount(register struct parse *p, register struct re_guts *g); |
*/ |
static sopno /* nesting depth */ |
pluscount(p, g) |
struct parse *p; |
register struct re_guts *g; |
{ |
register sop *scan; |
register sop s; |
register sopno plusnest = 0; |
register sopno maxnest = 0; |
if (p->error != 0) |
return(0); /* there may not be an OEND */ |
scan = g->strip + 1; |
do { |
s = *scan++; |
switch (OP(s)) { |
case OPLUS_: |
plusnest++; |
break; |
case O_PLUS: |
if (plusnest > maxnest) |
maxnest = plusnest; |
plusnest--; |
break; |
} |
} while (OP(s) != OEND); |
if (plusnest != 0) |
g->iflags |= BAD; |
return(maxnest); |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/regex/regcomp.ih |
---|
0,0 → 1,51 |
/* ========= begin header generated by ./mkh ========= */ |
#ifdef __cplusplus |
extern "C" { |
#endif |
/* === regcomp.c === */ |
static void p_ere (register struct parse *p, int stop); |
static void p_ere_exp (register struct parse *p); |
static void p_str (register struct parse *p); |
static void p_bre (register struct parse *p, register int end1, register int end2); |
static int p_simp_re (register struct parse *p, int starordinary); |
static int p_count (register struct parse *p); |
static void p_bracket (register struct parse *p); |
static void p_b_term (register struct parse *p, register cset *cs); |
static void p_b_cclass (register struct parse *p, register cset *cs); |
static void p_b_eclass (register struct parse *p, register cset *cs); |
static char p_b_symbol (register struct parse *p); |
static char p_b_coll_elem (register struct parse *p, int endc); |
static char othercase (int ch); |
static void bothcases (register struct parse *p, int ch); |
static void ordinary (register struct parse *p, register int ch); |
static void nonnewline (register struct parse *p); |
static void repeat (register struct parse *p, sopno start, int from, int to); |
static int seterr (register struct parse *p, int e); |
static cset *allocset (register struct parse *p); |
static void freeset (register struct parse *p, register cset *cs); |
static int freezeset (register struct parse *p, register cset *cs); |
static int firstch (register struct parse *p, register cset *cs); |
static int nch (register struct parse *p, register cset *cs); |
static void mcadd (register struct parse *p, register cset *cs, register char *cp); |
static void mcsub (register cset *cs, register char *cp); |
static int mcin (register cset *cs, register char *cp); |
static char *mcfind (register cset *cs, register char *cp); |
static void mcinvert (register struct parse *p, register cset *cs); |
static void mccase (register struct parse *p, register cset *cs); |
static int isinsets (register struct re_guts *g, int c); |
static int samesets (register struct re_guts *g, int c1, int c2); |
static void categorize (struct parse *p, register struct re_guts *g); |
static sopno dupl (register struct parse *p, sopno start, sopno finish); |
static void doemit (register struct parse *p, sop op, size_t opnd); |
static void doinsert (register struct parse *p, sop op, size_t opnd, sopno pos); |
static void dofwd (register struct parse *p, sopno pos, sop value); |
static void enlarge (register struct parse *p, sopno size); |
static void stripsnug (register struct parse *p, register struct re_guts *g); |
static void findmust (register struct parse *p, register struct re_guts *g); |
static sopno pluscount (register struct parse *p, register struct re_guts *g); |
#ifdef __cplusplus |
} |
#endif |
/* ========= end header generated by ./mkh ========= */ |
/programs/develop/libraries/menuetlibc/src/libc/posix/regex/regerror.c |
---|
0,0 → 1,127 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <sys/types.h> |
#include <stdio.h> |
#include <string.h> |
#include <ctype.h> |
#include <limits.h> |
#include <stdlib.h> |
#include <regex.h> |
#include "utils.h" |
#include "regerror.ih" |
/* |
= #define REG_NOMATCH 1 |
= #define REG_BADPAT 2 |
= #define REG_ECOLLATE 3 |
= #define REG_ECTYPE 4 |
= #define REG_EESCAPE 5 |
= #define REG_ESUBREG 6 |
= #define REG_EBRACK 7 |
= #define REG_EPAREN 8 |
= #define REG_EBRACE 9 |
= #define REG_BADBR 10 |
= #define REG_ERANGE 11 |
= #define REG_ESPACE 12 |
= #define REG_BADRPT 13 |
= #define REG_EMPTY 14 |
= #define REG_ASSERT 15 |
= #define REG_INVARG 16 |
= #define REG_ATOI 255 // convert name to number (!) |
= #define REG_ITOA 0400 // convert number to name (!) |
*/ |
static struct rerr { |
int code; |
char *name; |
char *explain; |
} rerrs[] = { |
REG_NOMATCH, "REG_NOMATCH", "regexec() failed to match", |
REG_BADPAT, "REG_BADPAT", "invalid regular expression", |
REG_ECOLLATE, "REG_ECOLLATE", "invalid collating element", |
REG_ECTYPE, "REG_ECTYPE", "invalid character class", |
REG_EESCAPE, "REG_EESCAPE", "trailing backslash (\\)", |
REG_ESUBREG, "REG_ESUBREG", "invalid backreference number", |
REG_EBRACK, "REG_EBRACK", "brackets ([ ]) not balanced", |
REG_EPAREN, "REG_EPAREN", "parentheses not balanced", |
REG_EBRACE, "REG_EBRACE", "braces not balanced", |
REG_BADBR, "REG_BADBR", "invalid repetition count(s)", |
REG_ERANGE, "REG_ERANGE", "invalid character range", |
REG_ESPACE, "REG_ESPACE", "out of memory", |
REG_BADRPT, "REG_BADRPT", "repetition-operator operand invalid", |
REG_EMPTY, "REG_EMPTY", "empty (sub)expression", |
REG_ASSERT, "REG_ASSERT", "\"can't happen\" -- you found a bug", |
REG_INVARG, "REG_INVARG", "invalid argument to regex routine", |
0, "", "*** unknown regexp error code ***", |
}; |
/* |
- regerror - the interface to error numbers |
= extern size_t regerror(int, const regex_t *, char *, size_t); |
*/ |
/* ARGSUSED */ |
size_t |
regerror(errcode, preg, errbuf, errbuf_size) |
int errcode; |
const regex_t *preg; |
char *errbuf; |
size_t errbuf_size; |
{ |
register struct rerr *r; |
register size_t len; |
register int target = errcode &~ REG_ITOA; |
register char *s; |
char convbuf[50]; |
if (errcode == REG_ATOI) |
s = regatoi(preg, convbuf); |
else { |
for (r = rerrs; r->code != 0; r++) |
if (r->code == target) |
break; |
if (errcode®_ITOA) { |
if (r->code != 0) |
(void) strcpy(convbuf, r->name); |
else |
sprintf(convbuf, "REG_0x%x", target); |
assert(strlen(convbuf) < sizeof(convbuf)); |
s = convbuf; |
} else |
s = r->explain; |
} |
len = strlen(s) + 1; |
if (errbuf_size > 0) { |
if (errbuf_size > len) |
(void) strcpy(errbuf, s); |
else { |
(void) strncpy(errbuf, s, errbuf_size-1); |
errbuf[errbuf_size-1] = '\0'; |
} |
} |
return(len); |
} |
/* |
- regatoi - internal routine to implement REG_ATOI |
== static char *regatoi(const regex_t *preg, char *localbuf); |
*/ |
static char * |
regatoi(preg, localbuf) |
const regex_t *preg; |
char *localbuf; |
{ |
register struct rerr *r; |
register size_t siz; |
register char *p; |
for (r = rerrs; r->code != 0; r++) |
if (strcmp(r->name, preg->re_endp) == 0) |
break; |
if (r->code == 0) |
return("0"); |
sprintf(localbuf, "%d", r->code); |
return(localbuf); |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/regex/regerror.ih |
---|
0,0 → 1,12 |
/* ========= begin header generated by ./mkh ========= */ |
#ifdef __cplusplus |
extern "C" { |
#endif |
/* === regerror.c === */ |
static char *regatoi (const regex_t *preg, char *localbuf); |
#ifdef __cplusplus |
} |
#endif |
/* ========= end header generated by ./mkh ========= */ |
/programs/develop/libraries/menuetlibc/src/libc/posix/regex/regex2.h |
---|
0,0 → 1,135 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
/* |
* First, the stuff that ends up in the outside-world include file |
= typedef off_t regoff_t; |
= typedef struct { |
= int re_magic; |
= size_t re_nsub; // number of parenthesized subexpressions |
= const char *re_endp; // end pointer for REG_PEND |
= struct re_guts *re_g; // none of your business :-) |
= } regex_t; |
= typedef struct { |
= regoff_t rm_so; // start of match |
= regoff_t rm_eo; // end of match |
= } regmatch_t; |
*/ |
/* |
* internals of regex_t |
*/ |
#define MAGIC1 ((('r'^0200)<<8) | 'e') |
/* |
* The internal representation is a *strip*, a sequence of |
* operators ending with an endmarker. (Some terminology etc. is a |
* historical relic of earlier versions which used multiple strips.) |
* Certain oddities in the representation are there to permit running |
* the machinery backwards; in particular, any deviation from sequential |
* flow must be marked at both its source and its destination. Some |
* fine points: |
* |
* - OPLUS_ and O_PLUS are *inside* the loop they create. |
* - OQUEST_ and O_QUEST are *outside* the bypass they create. |
* - OCH_ and O_CH are *outside* the multi-way branch they create, while |
* OOR1 and OOR2 are respectively the end and the beginning of one of |
* the branches. Note that there is an implicit OOR2 following OCH_ |
* and an implicit OOR1 preceding O_CH. |
* |
* In state representations, an operator's bit is on to signify a state |
* immediately *preceding* "execution" of that operator. |
*/ |
typedef unsigned long sop; /* strip operator */ |
typedef long sopno; |
#define OPRMASK 0xf8000000 |
#define OPDMASK 0x07ffffff |
#define OPSHIFT ((unsigned)27) |
#define OP(n) ((n)&OPRMASK) |
#define OPND(n) ((n)&OPDMASK) |
#define SOP(op, opnd) ((op)|(opnd)) |
/* operators meaning operand */ |
/* (back, fwd are offsets) */ |
#define OEND (1<<OPSHIFT) /* endmarker - */ |
#define OCHAR (2<<OPSHIFT) /* character unsigned char */ |
#define OBOL (3<<OPSHIFT) /* left anchor - */ |
#define OEOL (4<<OPSHIFT) /* right anchor - */ |
#define OANY (5<<OPSHIFT) /* . - */ |
#define OANYOF (6<<OPSHIFT) /* [...] set number */ |
#define OBACK_ (7<<OPSHIFT) /* begin \d paren number */ |
#define O_BACK (8<<OPSHIFT) /* end \d paren number */ |
#define OPLUS_ (9<<OPSHIFT) /* + prefix fwd to suffix */ |
#define O_PLUS (10<<OPSHIFT) /* + suffix back to prefix */ |
#define OQUEST_ (11<<OPSHIFT) /* ? prefix fwd to suffix */ |
#define O_QUEST (12<<OPSHIFT) /* ? suffix back to prefix */ |
#define OLPAREN (13<<OPSHIFT) /* ( fwd to ) */ |
#define ORPAREN (14<<OPSHIFT) /* ) back to ( */ |
#define OCH_ (15<<OPSHIFT) /* begin choice fwd to OOR2 */ |
#define OOR1 (16<<OPSHIFT) /* | pt. 1 back to OOR1 or OCH_ */ |
#define OOR2 (17<<OPSHIFT) /* | pt. 2 fwd to OOR2 or O_CH */ |
#define O_CH (18<<OPSHIFT) /* end choice back to OOR1 */ |
#define OBOW (19<<OPSHIFT) /* begin word - */ |
#define OEOW (20<<OPSHIFT) /* end word - */ |
/* |
* Structure for [] character-set representation. Character sets are |
* done as bit vectors, grouped 8 to a byte vector for compactness. |
* The individual set therefore has both a pointer to the byte vector |
* and a mask to pick out the relevant bit of each byte. A hash code |
* simplifies testing whether two sets could be identical. |
* |
* This will get trickier for multicharacter collating elements. As |
* preliminary hooks for dealing with such things, we also carry along |
* a string of multi-character elements, and decide the size of the |
* vectors at run time. |
*/ |
typedef struct { |
uch *ptr; /* -> uch [csetsize] */ |
uch mask; /* bit within array */ |
uch hash; /* hash code */ |
size_t smultis; |
char *multis; /* -> char[smulti] ab\0cd\0ef\0\0 */ |
} cset; |
/* note that CHadd and CHsub are unsafe, and CHIN doesn't yield 0/1 */ |
#define CHadd(cs, c) ((cs)->ptr[(uch)(c)] |= (cs)->mask, (cs)->hash += (c)) |
#define CHsub(cs, c) ((cs)->ptr[(uch)(c)] &= ~(cs)->mask, (cs)->hash -= (c)) |
#define CHIN(cs, c) ((cs)->ptr[(uch)(c)] & (cs)->mask) |
#define MCadd(p, cs, cp) mcadd(p, cs, cp) /* regcomp() internal fns */ |
#define MCsub(p, cs, cp) mcsub(p, cs, cp) |
#define MCin(p, cs, cp) mcin(p, cs, cp) |
/* stuff for character categories */ |
typedef unsigned char cat_t; |
/* |
* main compiled-expression structure |
*/ |
struct re_guts { |
int magic; |
# define MAGIC2 ((('R'^0200)<<8)|'E') |
sop *strip; /* malloced area for strip */ |
int csetsize; /* number of bits in a cset vector */ |
int ncsets; /* number of csets in use */ |
cset *sets; /* -> cset [ncsets] */ |
uch *setbits; /* -> uch[csetsize][ncsets/CHAR_BIT] */ |
int cflags; /* copy of regcomp() cflags argument */ |
sopno nstates; /* = number of sops */ |
sopno firststate; /* the initial OEND (normally 0) */ |
sopno laststate; /* the final OEND */ |
int iflags; /* internal flags */ |
# define USEBOL 01 /* used ^ */ |
# define USEEOL 02 /* used $ */ |
# define BAD 04 /* something wrong */ |
int nbol; /* number of ^ used */ |
int neol; /* number of $ used */ |
int ncategories; /* how many character categories */ |
cat_t *categories; /* ->catspace[-CHAR_MIN] */ |
char *must; /* match must contain this string */ |
int mlen; /* length of must */ |
size_t nsub; /* copy of re_nsub */ |
int backrefs; /* does it use back references? */ |
sopno nplus; /* how deep does it nest +s? */ |
/* catspace must be last */ |
cat_t catspace[1]; /* actually [NC] */ |
}; |
/* misc utilities */ |
#define OUT (CHAR_MAX+1) /* a non-character value */ |
#define ISWORD(c) (isalnum(c) || (c) == '_') |
/programs/develop/libraries/menuetlibc/src/libc/posix/regex/regexec.c |
---|
0,0 → 1,139 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
/* |
* the outer shell of regexec() |
* |
* This file includes engine.c *twice*, after muchos fiddling with the |
* macros that code uses. This lets the same code operate on two different |
* representations for state sets. |
*/ |
#include <sys/types.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include <limits.h> |
#include <ctype.h> |
#include <regex.h> |
#include "utils.h" |
#include "regex2.h" |
static int nope = 0; /* for use in asserts; shuts lint up */ |
/* macros for manipulating states, small version */ |
#define states long |
#define states1 states /* for later use in regexec() decision */ |
#define CLEAR(v) ((v) = 0) |
#define SET0(v, n) ((v) &= ~(1 << (n))) |
#define SET1(v, n) ((v) |= 1 << (n)) |
#define ISSET(v, n) ((v) & (1 << (n))) |
#define ASSIGN(d, s) ((d) = (s)) |
#define EQ(a, b) ((a) == (b)) |
#define STATEVARS int dummy /* dummy version */ |
#define STATESETUP(m, n) /* nothing */ |
#define STATETEARDOWN(m) /* nothing */ |
#define SETUP(v) ((v) = 0) |
#define onestate int |
#define INIT(o, n) ((o) = (unsigned)1 << (n)) |
#define INC(o) ((o) <<= 1) |
#define ISSTATEIN(v, o) ((v) & (o)) |
/* some abbreviations; note that some of these know variable names! */ |
/* do "if I'm here, I can also be there" etc without branches */ |
#define FWD(dst, src, n) ((dst) |= ((unsigned)(src)&(here)) << (n)) |
#define BACK(dst, src, n) ((dst) |= ((unsigned)(src)&(here)) >> (n)) |
#define ISSETBACK(v, n) ((v) & ((unsigned)here >> (n))) |
/* function names */ |
#define SNAMES /* engine.c looks after details */ |
#include "engine.c" |
/* now undo things */ |
#undef states |
#undef CLEAR |
#undef SET0 |
#undef SET1 |
#undef ISSET |
#undef ASSIGN |
#undef EQ |
#undef STATEVARS |
#undef STATESETUP |
#undef STATETEARDOWN |
#undef SETUP |
#undef onestate |
#undef INIT |
#undef INC |
#undef ISSTATEIN |
#undef FWD |
#undef BACK |
#undef ISSETBACK |
#undef SNAMES |
/* macros for manipulating states, large version */ |
#define states char * |
#define CLEAR(v) memset(v, 0, m->g->nstates) |
#define SET0(v, n) ((v)[n] = 0) |
#define SET1(v, n) ((v)[n] = 1) |
#define ISSET(v, n) ((v)[n]) |
#define ASSIGN(d, s) memcpy(d, s, m->g->nstates) |
#define EQ(a, b) (memcmp(a, b, m->g->nstates) == 0) |
#define STATEVARS int vn; char *space |
#define STATESETUP(m, nv) { (m)->space = malloc((nv)*(m)->g->nstates); \ |
if ((m)->space == NULL) return(REG_ESPACE); \ |
(m)->vn = 0; } |
#define STATETEARDOWN(m) { free((m)->space); } |
#define SETUP(v) ((v) = &m->space[m->vn++ * m->g->nstates]) |
#define onestate int |
#define INIT(o, n) ((o) = (n)) |
#define INC(o) ((o)++) |
#define ISSTATEIN(v, o) ((v)[o]) |
/* some abbreviations; note that some of these know variable names! */ |
/* do "if I'm here, I can also be there" etc without branches */ |
#define FWD(dst, src, n) ((dst)[here+(n)] |= (src)[here]) |
#define BACK(dst, src, n) ((dst)[here-(n)] |= (src)[here]) |
#define ISSETBACK(v, n) ((v)[here - (n)]) |
/* function names */ |
#define LNAMES /* flag */ |
#include "engine.c" |
/* |
- regexec - interface for matching |
= extern int regexec(const regex_t *, const char *, size_t, \ |
= regmatch_t [], int); |
= #define REG_NOTBOL 00001 |
= #define REG_NOTEOL 00002 |
= #define REG_STARTEND 00004 |
= #define REG_TRACE 00400 // tracing of execution |
= #define REG_LARGE 01000 // force large representation |
= #define REG_BACKR 02000 // force use of backref code |
* |
* We put this here so we can exploit knowledge of the state representation |
* when choosing which matcher to call. Also, by this point the matchers |
* have been prototyped. |
*/ |
int /* 0 success, REG_NOMATCH failure */ |
regexec(preg, string, nmatch, pmatch, eflags) |
const regex_t *preg; |
const char *string; |
size_t nmatch; |
regmatch_t pmatch[]; |
int eflags; |
{ |
register struct re_guts *g = preg->re_g; |
#ifdef REDEBUG |
# define GOODFLAGS(f) (f) |
#else |
# define GOODFLAGS(f) ((f)&(REG_NOTBOL|REG_NOTEOL|REG_STARTEND)) |
#endif |
if (preg->re_magic != MAGIC1 || g->magic != MAGIC2) |
return(REG_BADPAT); |
assert(!(g->iflags&BAD)); |
if (g->iflags&BAD) /* backstop for no-debug case */ |
return(REG_BADPAT); |
eflags = GOODFLAGS(eflags); |
if (g->nstates <= CHAR_BIT*sizeof(states1) && !(eflags®_LARGE)) |
return(smatcher(g, (char *)string, nmatch, pmatch, eflags)); |
else |
return(lmatcher(g, (char *)string, nmatch, pmatch, eflags)); |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/regex/regfree.c |
---|
0,0 → 1,38 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <sys/types.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <regex.h> |
#include "utils.h" |
#include "regex2.h" |
/* |
- regfree - free everything |
= extern void regfree(regex_t *); |
*/ |
void |
regfree(preg) |
regex_t *preg; |
{ |
register struct re_guts *g; |
if (preg->re_magic != MAGIC1) /* oops */ |
return; /* nice to complain, but hard */ |
g = preg->re_g; |
if (g == NULL || g->magic != MAGIC2) /* oops again */ |
return; |
preg->re_magic = 0; /* mark it invalid */ |
g->magic = 0; /* mark it invalid */ |
if (g->strip != NULL) |
free((char *)g->strip); |
if (g->sets != NULL) |
free((char *)g->sets); |
if (g->setbits != NULL) |
free((char *)g->setbits); |
if (g->must != NULL) |
free(g->must); |
free((char *)g); |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/regex/split.c |
---|
0,0 → 1,317 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <stdio.h> |
#include <string.h> |
/* |
- split - divide a string into fields, like awk split() |
= int split(char *string, char *fields[], int nfields, char *sep); |
*/ |
int /* number of fields, including overflow */ |
split(string, fields, nfields, sep) |
char *string; |
char *fields[]; /* list is not NULL-terminated */ |
int nfields; /* number of entries available in fields[] */ |
char *sep; /* "" white, "c" single char, "ab" [ab]+ */ |
{ |
register char *p = string; |
register char c; /* latest character */ |
register char sepc = sep[0]; |
register char sepc2; |
register int fn; |
register char **fp = fields; |
register char *sepp; |
register int trimtrail; |
/* white space */ |
if (sepc == '\0') { |
while ((c = *p++) == ' ' || c == '\t') |
continue; |
p--; |
trimtrail = 1; |
sep = " \t"; /* note, code below knows this is 2 long */ |
sepc = ' '; |
} else |
trimtrail = 0; |
sepc2 = sep[1]; /* now we can safely pick this up */ |
/* catch empties */ |
if (*p == '\0') |
return(0); |
/* single separator */ |
if (sepc2 == '\0') { |
fn = nfields; |
for (;;) { |
*fp++ = p; |
fn--; |
if (fn == 0) |
break; |
while ((c = *p++) != sepc) |
if (c == '\0') |
return(nfields - fn); |
*(p-1) = '\0'; |
} |
/* we have overflowed the fields vector -- just count them */ |
fn = nfields; |
for (;;) { |
while ((c = *p++) != sepc) |
if (c == '\0') |
return(fn); |
fn++; |
} |
/* not reached */ |
} |
/* two separators */ |
if (sep[2] == '\0') { |
fn = nfields; |
for (;;) { |
*fp++ = p; |
fn--; |
while ((c = *p++) != sepc && c != sepc2) |
if (c == '\0') { |
if (trimtrail && **(fp-1) == '\0') |
fn++; |
return(nfields - fn); |
} |
if (fn == 0) |
break; |
*(p-1) = '\0'; |
while ((c = *p++) == sepc || c == sepc2) |
continue; |
p--; |
} |
/* we have overflowed the fields vector -- just count them */ |
fn = nfields; |
while (c != '\0') { |
while ((c = *p++) == sepc || c == sepc2) |
continue; |
p--; |
fn++; |
while ((c = *p++) != '\0' && c != sepc && c != sepc2) |
continue; |
} |
/* might have to trim trailing white space */ |
if (trimtrail) { |
p--; |
while ((c = *--p) == sepc || c == sepc2) |
continue; |
p++; |
if (*p != '\0') { |
if (fn == nfields+1) |
*p = '\0'; |
fn--; |
} |
} |
return(fn); |
} |
/* n separators */ |
fn = 0; |
for (;;) { |
if (fn < nfields) |
*fp++ = p; |
fn++; |
for (;;) { |
c = *p++; |
if (c == '\0') |
return(fn); |
sepp = sep; |
while ((sepc = *sepp++) != '\0' && sepc != c) |
continue; |
if (sepc != '\0') /* it was a separator */ |
break; |
} |
if (fn < nfields) |
*(p-1) = '\0'; |
for (;;) { |
c = *p++; |
sepp = sep; |
while ((sepc = *sepp++) != '\0' && sepc != c) |
continue; |
if (sepc == '\0') /* it wasn't a separator */ |
break; |
} |
p--; |
} |
/* not reached */ |
} |
#ifdef TEST_SPLIT |
/* |
* test program |
* pgm runs regression |
* pgm sep splits stdin lines by sep |
* pgm str sep splits str by sep |
* pgm str sep n splits str by sep n times |
*/ |
int |
main(argc, argv) |
int argc; |
char *argv[]; |
{ |
char buf[512]; |
register int n; |
# define MNF 10 |
char *fields[MNF]; |
if (argc > 4) |
for (n = atoi(argv[3]); n > 0; n--) { |
(void) strcpy(buf, argv[1]); |
} |
else if (argc > 3) |
for (n = atoi(argv[3]); n > 0; n--) { |
(void) strcpy(buf, argv[1]); |
(void) split(buf, fields, MNF, argv[2]); |
} |
else if (argc > 2) |
dosplit(argv[1], argv[2]); |
else if (argc > 1) |
while (fgets(buf, sizeof(buf), stdin) != NULL) { |
buf[strlen(buf)-1] = '\0'; /* stomp newline */ |
dosplit(buf, argv[1]); |
} |
else |
regress(); |
exit(0); |
} |
dosplit(string, seps) |
char *string; |
char *seps; |
{ |
# define NF 5 |
char *fields[NF]; |
register int nf; |
nf = split(string, fields, NF, seps); |
print(nf, NF, fields); |
} |
print(nf, nfp, fields) |
int nf; |
int nfp; |
char *fields[]; |
{ |
register int fn; |
register int bound; |
bound = (nf > nfp) ? nfp : nf; |
printf("%d:\t", nf); |
for (fn = 0; fn < bound; fn++) |
printf("\"%s\"%s", fields[fn], (fn+1 < nf) ? ", " : "\n"); |
} |
#define RNF 5 /* some table entries know this */ |
struct { |
char *str; |
char *seps; |
int nf; |
char *fi[RNF]; |
} tests[] = { |
"", " ", 0, { "" }, |
" ", " ", 2, { "", "" }, |
"x", " ", 1, { "x" }, |
"xy", " ", 1, { "xy" }, |
"x y", " ", 2, { "x", "y" }, |
"abc def g ", " ", 5, { "abc", "def", "", "g", "" }, |
" a bcd", " ", 4, { "", "", "a", "bcd" }, |
"a b c d e f", " ", 6, { "a", "b", "c", "d", "e f" }, |
" a b c d ", " ", 6, { "", "a", "b", "c", "d " }, |
"", " _", 0, { "" }, |
" ", " _", 2, { "", "" }, |
"x", " _", 1, { "x" }, |
"x y", " _", 2, { "x", "y" }, |
"ab _ cd", " _", 2, { "ab", "cd" }, |
" a_b c ", " _", 5, { "", "a", "b", "c", "" }, |
"a b c_d e f", " _", 6, { "a", "b", "c", "d", "e f" }, |
" a b c d ", " _", 6, { "", "a", "b", "c", "d " }, |
"", " _~", 0, { "" }, |
" ", " _~", 2, { "", "" }, |
"x", " _~", 1, { "x" }, |
"x y", " _~", 2, { "x", "y" }, |
"ab _~ cd", " _~", 2, { "ab", "cd" }, |
" a_b c~", " _~", 5, { "", "a", "b", "c", "" }, |
"a b_c d~e f", " _~", 6, { "a", "b", "c", "d", "e f" }, |
"~a b c d ", " _~", 6, { "", "a", "b", "c", "d " }, |
"", " _~-", 0, { "" }, |
" ", " _~-", 2, { "", "" }, |
"x", " _~-", 1, { "x" }, |
"x y", " _~-", 2, { "x", "y" }, |
"ab _~- cd", " _~-", 2, { "ab", "cd" }, |
" a_b c~", " _~-", 5, { "", "a", "b", "c", "" }, |
"a b_c-d~e f", " _~-", 6, { "a", "b", "c", "d", "e f" }, |
"~a-b c d ", " _~-", 6, { "", "a", "b", "c", "d " }, |
"", " ", 0, { "" }, |
" ", " ", 2, { "", "" }, |
"x", " ", 1, { "x" }, |
"xy", " ", 1, { "xy" }, |
"x y", " ", 2, { "x", "y" }, |
"abc def g ", " ", 4, { "abc", "def", "g", "" }, |
" a bcd", " ", 3, { "", "a", "bcd" }, |
"a b c d e f", " ", 6, { "a", "b", "c", "d", "e f" }, |
" a b c d ", " ", 6, { "", "a", "b", "c", "d " }, |
"", "", 0, { "" }, |
" ", "", 0, { "" }, |
"x", "", 1, { "x" }, |
"xy", "", 1, { "xy" }, |
"x y", "", 2, { "x", "y" }, |
"abc def g ", "", 3, { "abc", "def", "g" }, |
"\t a bcd", "", 2, { "a", "bcd" }, |
" a \tb\t c ", "", 3, { "a", "b", "c" }, |
"a b c d e ", "", 5, { "a", "b", "c", "d", "e" }, |
"a b\tc d e f", "", 6, { "a", "b", "c", "d", "e f" }, |
" a b c d e f ", "", 6, { "a", "b", "c", "d", "e f " }, |
NULL, NULL, 0, { NULL }, |
}; |
regress() |
{ |
char buf[512]; |
register int n; |
char *fields[RNF+1]; |
register int nf; |
register int i; |
register int printit; |
register char *f; |
for (n = 0; tests[n].str != NULL; n++) { |
(void) strcpy(buf, tests[n].str); |
fields[RNF] = NULL; |
nf = split(buf, fields, RNF, tests[n].seps); |
printit = 0; |
if (nf != tests[n].nf) { |
printf("split `%s' by `%s' gave %d fields, not %d\n", |
tests[n].str, tests[n].seps, nf, tests[n].nf); |
printit = 1; |
} else if (fields[RNF] != NULL) { |
printf("split() went beyond array end\n"); |
printit = 1; |
} else { |
for (i = 0; i < nf && i < RNF; i++) { |
f = fields[i]; |
if (f == NULL) |
f = "(NULL)"; |
if (strcmp(f, tests[n].fi[i]) != 0) { |
printf("split `%s' by `%s', field %d is `%s', not `%s'\n", |
tests[n].str, tests[n].seps, |
i, fields[i], tests[n].fi[i]); |
printit = 1; |
} |
} |
} |
if (printit) |
print(nf, RNF, fields); |
} |
} |
#endif |
/programs/develop/libraries/menuetlibc/src/libc/posix/regex/utils.h |
---|
0,0 → 1,19 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
/* utility definitions */ |
#define DUPMAX _POSIX2_RE_DUP_MAX /* xxx is this right? */ |
#define INFINITY (DUPMAX + 1) |
#define NC (CHAR_MAX - CHAR_MIN + 1) |
typedef unsigned char uch; |
/* switch off assertions (if not already off) if no REDEBUG */ |
#ifndef REDEBUG |
#ifndef NDEBUG |
#define NDEBUG /* no assertions please */ |
#endif |
#endif |
#include <assert.h> |
/* for old systems with bcopy() but no memmove() */ |
#ifdef USEBCOPY |
#define memmove(d, s, c) bcopy(s, d, c) |
#endif |
/programs/develop/libraries/menuetlibc/src/libc/posix/setjmp/Makefile |
---|
0,0 → 1,3 |
THIS_SRCS = siglongj.s sigsetjm.s |
include $(MENUET_LIBC_TOPDIR)/Make.rules |
/programs/develop/libraries/menuetlibc/src/libc/posix/setjmp/siglongj.s |
---|
0,0 → 1,5 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include<libc/asm.h> |
MK_C_SYM(siglongjmp) |
jmp C_SYM(longjmp) |
/programs/develop/libraries/menuetlibc/src/libc/posix/setjmp/sigsetjm.s |
---|
0,0 → 1,5 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include<libc/asm.h> |
MK_C_SYM(sigsetjmp) |
jmp C_SYM(setjmp) |
/programs/develop/libraries/menuetlibc/src/libc/posix/signal/Makefile |
---|
0,0 → 1,4 |
THIS_SRCS = itimer.c kill.c sigaddse.c sigdelse.c sigempty.c sigfills.c \ |
sigismem.c sigpendi.c sigprocm.c sigsuspe.c |
include $(MENUET_LIBC_TOPDIR)/Make.rules |
/programs/develop/libraries/menuetlibc/src/libc/posix/signal/itimer.c |
---|
0,0 → 1,24 |
/* Copyright (C) 1995 Charles Sandmann (sandmann@clio.rice.edu) |
setitimer implmentation - used for profiling and alarm |
BUGS: ONLY ONE AT A TIME, first pass code |
This software may be freely distributed, no warranty. */ |
#include <libc/stubs.h> |
#include <sys/time.h> |
#include <errno.h> |
#include <signal.h> |
#include <assert.h> |
static struct itimerval real, prof; |
/* not right, should compute from current tic count. Do later */ |
int getitimer(int which, struct itimerval *value) |
{ |
errno = EINVAL; |
return -1; |
} |
int setitimer(int which, struct itimerval *value, struct itimerval *ovalue) |
{ |
return -EPERM; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/signal/kill.c |
---|
0,0 → 1,8 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <signal.h> |
#include <unistd.h> |
int kill(pid_t pid, int sig) |
{ |
if(pid==-1) __menuet__sys_exit(); |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/signal/sigaddse.c |
---|
0,0 → 1,20 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <errno.h> |
#include <signal.h> |
int |
sigaddset(sigset_t *_set, int _signo) |
{ |
if (_set == 0) |
{ |
errno = EINVAL; |
return -1; |
} |
if (_signo < 0 || _signo >= 320) |
{ |
errno = EINVAL; |
return -1; |
} |
_set->__bits[_signo>>5] |= (1U << (_signo&31)); |
return 0; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/signal/sigdelse.c |
---|
0,0 → 1,20 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <errno.h> |
#include <signal.h> |
int |
sigdelset(sigset_t *_set, int _signo) |
{ |
if (_set == 0) |
{ |
errno = EINVAL; |
return -1; |
} |
if (_signo < 0 || _signo >= 320) |
{ |
errno = EINVAL; |
return -1; |
} |
_set->__bits[_signo>>5] &= ~(1U << (_signo&31)); |
return 0; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/signal/sigempty.c |
---|
0,0 → 1,17 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <errno.h> |
#include <signal.h> |
int |
sigemptyset(sigset_t *_set) |
{ |
int i; |
if (_set == 0) |
{ |
errno = EINVAL; |
return -1; |
} |
for (i=0; i<10; i++) |
_set->__bits[i] = 0; |
return 0; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/signal/sigfills.c |
---|
0,0 → 1,16 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <errno.h> |
#include <signal.h> |
int |
sigfillset(sigset_t *_set) |
{ |
if (_set == 0) |
{ |
errno = EINVAL; |
return -1; |
} |
sigemptyset(_set); |
_set->__bits[9] = 0x7fff; /* SIGABRT (288) .. SIGTRAP (302) */ |
return 0; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/signal/sigismem.c |
---|
0,0 → 1,16 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <errno.h> |
#include <signal.h> |
int |
sigismember(const sigset_t *_set, int _signo) |
{ |
if (_set == 0) |
{ |
errno = EINVAL; |
return -1; |
} |
if (_signo < 0 || _signo >= 320) |
return 0; |
return _set->__bits[_signo >> 5] & (1U<<(_signo&31)) ? 1 : 0; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/signal/sigpendi.c |
---|
0,0 → 1,8 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <signal.h> |
int |
sigpending(sigset_t *_set) |
{ |
return sigemptyset(_set); |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/signal/sigprocm.c |
---|
0,0 → 1,9 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <signal.h> |
/* ARGSUSED */ |
int |
sigprocmask(int _how, const sigset_t *_set, sigset_t *_oset) |
{ |
return 0; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/signal/sigsuspe.c |
---|
0,0 → 1,9 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <signal.h> |
/* ARGSUSED */ |
int |
sigsuspend(const sigset_t *_set) |
{ |
return 0; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/stdio/Makefile |
---|
0,0 → 1,3 |
THIS_SRCS = fdopen.c fileno.c popen.c |
include $(MENUET_LIBC_TOPDIR)/Make.rules |
/programs/develop/libraries/menuetlibc/src/libc/posix/stdio/fdopen.c |
---|
0,0 → 1,67 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <libc/stubs.h> |
#include <sys/types.h> |
#include <stdio.h> |
#include <fcntl.h> |
#include <unistd.h> |
#include <io.h> |
#include <libc/file.h> |
#include <libc/local.h> |
FILE * |
fdopen(int fildes, const char *mode) |
{ |
FILE *f; |
int rw, oflags = 0; |
char tbchar; |
f = __alloc_file(); |
if (f == NULL) |
return NULL; |
rw = (mode[1] == '+') || (mode[1] && (mode[2] == '+')); |
switch (*mode) |
{ |
case 'a': |
oflags = O_CREAT | (rw ? O_RDWR : O_WRONLY); |
break; |
case 'r': |
oflags = rw ? O_RDWR : O_RDONLY; |
break; |
case 'w': |
oflags = O_TRUNC | O_CREAT | (rw ? O_RDWR : O_WRONLY); |
break; |
default: |
return (NULL); |
} |
if (mode[1] == '+') |
tbchar = mode[2]; |
else |
tbchar = mode[1]; |
if (tbchar == 't') |
oflags |= O_TEXT; |
else if (tbchar == 'b') |
oflags |= O_BINARY; |
else |
oflags |= (_fmode & (O_TEXT|O_BINARY)); |
if (*mode == 'a') |
lseek(fildes, 0, SEEK_END); |
f->_cnt = 0; |
f->_file = fildes; |
f->_bufsiz = 0; |
if (rw) |
f->_flag = _IORW; |
else if (*mode == 'r') |
f->_flag = _IOREAD; |
else |
f->_flag = _IOWRT; |
f->_base = f->_ptr = NULL; |
setmode(fildes, oflags & (O_TEXT|O_BINARY)); |
return f; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/stdio/fileno.c |
---|
0,0 → 1,10 |
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ |
#include <stdio.h> |
#include <libc/file.h> |
#undef fileno |
int |
fileno(FILE *stream) |
{ |
return stream ? stream->_file : -1; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/stdio/popen.c |
---|
0,0 → 1,220 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
/* |
This is popen() and pclose() for MSDOS. They were developed using |
Microsoft C, but should port easily to DOS C any compiler. |
Original author: pacetti@fl-ngnet.army.mil |
These routines are hacks, that is they SIMULATE thier UNIX |
counterparts. Since MSDOS and won't allow concurrent process spawning, |
you can't really pipe. I came up with this nearly stupid way around |
piping because I wanted to have some portability between UNIX and MSDOS. |
I'm probably not the first person to have this idea or implement it, but |
I think I'm the first to give it away for free (no points?!). |
The functions simulate popen() and pclose() by redirecting stdin or |
stdout, then spawning a child processes via system(). |
If you popen() for read, the stdout is redirected to a temporary |
file, and the child is spawned. The stdout is reopened via dup2(), the |
temporary file is opened for read and a file pointer to it is returned. |
If you popen() for write, a temporary file is opened for write, and |
a file pointer to it is returned. When you pclose(), the stdin is |
redirected to the temporary file and the child is spawned. |
In both cases, pclose() closes and unlinks the temporary file. |
A static linked list of C structures is built to store necessary |
info for all popen()ed files so you can popen() more than one file at |
a time. |
The popen() function will return NULL on an error, or a valid FILE |
*pointer on a successful open. The pclose() function will return |
negative one (-1) on an error or zero (0) on a successful close. |
The function prototypes are: |
FILE *popen(command, mode) |
char *command, char *mode; |
int pclose(pp) |
FILE *pp; |
Where command is a character string equivilant to a MSDOS command |
line, mode is "r" for read or "w" for write, and pp is a pointer to a |
file opened through popen(). |
A main() function has been included for testing purposes, to compile |
it define the preprocessor token TEST at compile time. |
*/ |
#include <libc/stubs.h> |
#include <io.h> |
#include <errno.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include <unistd.h> |
#include <libc/file.h> |
/* hold file pointer, descriptor, command, mode, temporary file name */ |
struct pipe_list { |
FILE *fp; |
int fd; |
char *command, mode[10], temp_name[FILENAME_MAX]; |
struct pipe_list *next; |
}; |
/* static, global list pointer */ |
static struct pipe_list *pl = NULL; |
FILE * |
popen (const char *cm, const char *md) /* program name, pipe mode */ |
{ |
struct pipe_list *l1, *l2; |
static char *tn = NULL; /* temporary file basename */ |
if (!tn) |
if ((tn = tmpnam(0)) == NULL) |
return NULL; |
/* make new node */ |
if ((l1 = (struct pipe_list *) malloc (sizeof (struct pipe_list))) == NULL) |
return NULL; |
/* zero out elements to we'll get here */ |
l1->fd = 0; |
l1->fp = NULL; |
l1->next = NULL; |
/* if empty list - just grab new node */ |
if (!pl) |
pl = l1; |
else |
{ |
/* otherwise, find last node in list */ |
++(l1->fd); |
l2 = pl; |
while (l2->next) |
{ |
++(l1->fd); |
l2 = l2->next; |
}; |
/* add new node to list */ |
l2->next = l1; |
} |
/* stick in elements we know already */ |
strcpy (l1->mode, md); |
sprintf (l1->temp_name, "%s.%d", tn, l1->fd); |
/* if can save the program name, build temp file */ |
if ((l1->command = malloc(strlen(cm)+1))) |
{ |
strcpy(l1->command, cm); |
/* if caller wants to read */ |
if (l1->mode[0] == 'r') |
{ |
/* dup stdout */ |
if ((l1->fd = dup (fileno (stdout))) == EOF) |
l1->fp = NULL; |
else if (!(l1->fp = freopen (l1->temp_name, "wb", stdout))) |
l1->fp = NULL; |
else |
/* exec cmd */ |
if (system (cm) == EOF) |
l1->fp = NULL; |
/* reopen real stdout */ |
if (dup2 (l1->fd, fileno (stdout)) == EOF) |
{ |
l1->fp = NULL; |
close(l1->fd); |
} |
else |
/* open file for reader */ |
l1->fp = fopen (l1->temp_name, l1->mode); |
} |
else |
/* if caller wants to write */ |
if (l1->mode[0] == 'w') |
/* open temp file */ |
l1->fp = fopen (l1->temp_name, l1->mode); |
else |
/* unknown mode */ |
l1->fp = NULL; |
} |
return l1->fp; /* return == NULL ? ERROR : OK */ |
} |
int |
pclose (FILE *pp) |
{ |
struct pipe_list *l1, *l2; /* list pointers */ |
int retval=0; /* function return value */ |
/* if pointer is first node */ |
if (pl->fp == pp) |
{ |
/* save node and take it out the list */ |
l1 = pl; |
pl = l1->next; |
} |
else |
/* if more than one node in list */ |
if (pl->next) |
{ |
/* find right node */ |
for (l2 = pl, l1 = pl->next; l1; l2 = l1, l1 = l2->next) |
if (l1->fp == pp) |
break; |
/* take node out of list */ |
l2->next = l1->next; |
} |
else |
return -1; |
/* if FILE not in list - return error */ |
if (l1->fp == pp) |
{ |
/* close the (hopefully) popen()ed file */ |
fclose (l1->fp); |
/* if pipe was opened to write */ |
if (l1->mode[0] == 'w') |
{ |
/* dup stdin */ |
if ((l1->fd = dup (fileno (stdin))) == EOF) |
retval = -1; |
else |
/* open temp stdin */ |
if (!(l1->fp = freopen (l1->temp_name, "rb", stdin))) |
retval = -1; |
else |
/* exec cmd */ |
if (system (l1->command) == EOF) |
retval = -1; |
else |
{ |
/* reopen stdin */ |
if (dup2 (l1->fd, fileno (stdin)) == EOF) |
retval = -1; |
close(l1->fd); |
} |
} |
else |
/* if pipe was opened to read */ |
if (l1->mode[0] == 'r') |
retval = 0; |
else |
/* invalid mode */ |
retval = -1; |
} |
remove (l1->temp_name); /* remove temporary file */ |
free (l1->command); /* dealloc memory */ |
free (l1); /* dealloc memory */ |
l1 = NULL; /* make pointer bogus */ |
return retval; /* retval==0 ? OK : ERROR */ |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/sys/Makefile |
---|
0,0 → 1,14 |
all: |
make -C stat |
make -C times |
make -C wait |
clean: |
make -C stat clean |
make -C times clean |
make -C wait clean |
depend: |
make -C stat depend |
make -C times depend |
make -C wait depend |
/programs/develop/libraries/menuetlibc/src/libc/posix/sys/stat/Makefile |
---|
0,0 → 1,4 |
THIS_SRCS = chmod.c filelen.c fixpath.c fstat.c is_exec.c mkdir.c mkfifo.c \ |
stat.c st_loss.c umask.c xstat.c |
include $(MENUET_LIBC_TOPDIR)/Make.rules |
/programs/develop/libraries/menuetlibc/src/libc/posix/sys/stat/chmod.c |
---|
0,0 → 1,26 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <libc/stubs.h> |
#include <sys/stat.h> |
#include <io.h> |
int |
chmod(const char *filename, int pmode) |
{ |
int dmode; |
unsigned attr = _chmod(filename, 0, 0); |
if (attr == -1) |
return -1; |
if(pmode & S_IWUSR) /* Only implemented toggle is write/nowrite */ |
dmode = 0; /* Normal file */ |
else |
dmode = 1; /* Readonly file */ |
/* Must clear the directory and volume bits, otherwise 214301 fails. |
Unused bits left alone (some network redirectors use them). */ |
if (_chmod(filename, 1, (attr & 0xffe6) | dmode) == -1) |
return -1; |
return 0; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/sys/stat/filelen.c |
---|
0,0 → 1,19 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
/* This is file FILELEN.C */ |
/* |
* Copyright (c) 1994 Eli Zaretskii <eliz@is.elta.co.il> |
* |
* This software may be used freely so long as this copyright notice is |
* left intact. There is no warranty on this software. |
* |
*/ |
#include <errno.h> |
#include <libc/dosio.h> |
long __filelength(int); |
long __filelength(int fhandle) |
{ |
return dosemu_iosize(fhandle); |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/sys/stat/fixpath.c |
---|
0,0 → 1,41 |
#include <libc/stubs.h> |
#include <stdio.h> /* For FILENAME_MAX */ |
#include <errno.h> /* For errno */ |
#include <string.h> /* For strlen() */ |
#include <sys/stat.h> |
#include <libc/dosio.h> |
static inline int is_slash(char c) |
{ |
return c=='/' || c=='\\'; |
} |
void fix_slashes(char * in,char * out) |
{ |
int slash_count; |
for(slash_count=1;in && out && *in;in++) |
{ |
if(is_slash(*in)) |
{ |
slash_count++; |
continue; |
} else { |
if(slash_count) |
{ |
slash_count=0; |
*out++='/'; |
} |
*out++=*in; |
} |
} |
*out='\0'; |
} |
char * __libc_combine_path(char * c); |
void _fixpath(const char *in, char *out) |
{ |
char * combined; |
combined=__libc_combine_path((char *)in); |
fix_slashes(combined,out); |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/sys/stat/fstat.c |
---|
0,0 → 1,26 |
#include <libc/stubs.h> |
#include <string.h> |
#include <stdlib.h> |
#include <stdio.h> |
#include <errno.h> |
#include <time.h> |
#include <unistd.h> |
#include <sys/types.h> |
#include <sys/stat.h> |
#include <libc/farptrgs.h> |
#include <libc/bss.h> |
#include <menuet/os.h> |
#include "../../../dos/dos_emu/dosemuin.h" |
#include "xstat.h" |
int fstat(int handle, struct stat *statbuf) |
{ |
if (handle < 0 || handle >= _MAX_HANDLES) |
{ |
errno = EBADF; |
return -1; |
} |
return stat(_io_handles[handle].filename, statbuf); |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/sys/stat/is_exec.c |
---|
0,0 → 1,125 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
/* IS_EXEC.C |
* |
* Given a filename or a file handle, and the extension of the file, |
* determine if the file is executable. |
* First, the file extension is checked in case it uniquely identifies |
* the file as either an executable or not. Failing this, the first |
* two bytes of the file are tested for known signatures of executable |
* files. |
* |
* Copyright (c) 1994 Eli Zaretskii <eliz@is.elta.co.il> |
* |
* This software may be used freely so long as this copyright notice is |
* left intact. There is no warranty on this software. |
* |
*/ |
#include <libc/stubs.h> |
#include <stdio.h> |
#include <string.h> |
#include <errno.h> |
#include <libc/farptrgs.h> |
#include <libc/dosio.h> |
extern unsigned short _djstat_flags; |
unsigned short _get_magic(const char *, int); |
int _is_executable(const char *, int, const char *); |
/* |
* Read a MAGIC NUMBER from a given file. These are the first |
* two bytes of the file, if we look at them as an unsigned short. */ |
#define _STAT_EXEC_EXT 2 /* get execute bits from file extension? */ |
#define _STAT_EXEC_MAGIC 4 /* get execute bits from magic signature? */ |
unsigned short _get_magic(const char *s, int fh) |
{ |
} |
/* A list of extensions which designate executable files. These |
are NOT tested for the magic number. */ |
static char executables[] = "|EXE|COM|BAT|BTM|DLL|VXD|"; |
/* A list of extensions which belong to files known to NEVER be |
executables. These exist to minimize read()'ing files while |
detecting executables by magic number. You are welcome to |
add to this list, but remember: only extensions which could |
NEVER be present in executables should go here. */ |
static char non_executables[] = "\ |
|A|A01|A02|A03|A04|A05|ADL|ARC|ARJ|ASC|ASM|AUX|AWK\ |
|BAS|BIB|BGI|BMP\ |
|C|CC|CFG|CGZ|CH3|CHR|CI|CLP|CMF|CPI|CPP|CXX\ |
|DAT|DBF|DIZ|DOC|DVI\ |
|E|EL|ELC\ |
|F77|FN3\ |
|GIF|GZ\ |
|H|HLP|HPP|HXX\ |
|ICO|IN|INC|INF|INI\ |
|JPG\ |
|L|LEX|LF|LIB|LOG|LST|LZH\ |
|M|MAK|MAP|MF|MID|MPG\ |
|O|OBJ\ |
|PAK|PAS|PBM|PCD|PCX|PDS|PIC|PIF|PN3|PRJ|PS\ |
|RAS|RGB|RLE\ |
|S|SND|SY3\ |
|TAR|TAZ|TEX|TGA|TGZ|TIF|TXH|TXI|TXT\ |
|VOC\ |
|WAV|WK1|WK3|WKB|WQ1|WQ3|WQ4|WQ5|WQ6|WQ!\ |
|XBM\ |
|Y\ |
|ZIP|ZOO|"; |
int _is_executable(const char *filename, int fhandle, const char *extension) |
{ |
if (!extension && filename) |
{ |
const char *cp, *ep=0; |
for (cp=filename; *cp; cp++) |
{ |
if (*cp == '.') |
ep = cp; |
if (*cp == '/' || *cp == '\\' || *cp == ':') |
ep = 0; |
} |
extension = ep; |
} |
if ((_djstat_flags & _STAT_EXEC_EXT) == 0 |
&& extension |
&& *extension |
&& strlen(extension) <= ((extension[0]=='.') ? 4 : 3)) |
{ |
/* Search the list of extensions in executables[]. */ |
char tmp_buf[6]; |
tmp_buf[0] = '|'; |
strcpy(tmp_buf+1, *extension == '.' ? extension + 1 : extension); |
strcat(tmp_buf, "|"); |
if (strstr(non_executables, tmp_buf)) |
return 0; |
else if (strstr(executables, tmp_buf)) |
return 1; |
} |
/* No extension, or extension doesn't define execute |
bits unambiguously. We are in for some dirty work. |
Read the first two bytes of the file and see if they |
are any of the known magic numbers which designate |
executable files. |
Unix-like shells, which have executable shell scripts |
without extensions and DON'T have "#!" as their FIRST |
TWO CHARACTERS, lose here. Sorry, folks. */ |
if ( (_djstat_flags & _STAT_EXEC_MAGIC) == 0 ) |
{ |
switch (_get_magic(filename, fhandle)) |
{ |
case 0x5a4d: /* "MZ" */ |
case 0x010b: |
case 0x014c: |
case 0x2123: /* "#!" */ |
return 1; |
} |
} |
return 0; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/sys/stat/mkdir.c |
---|
0,0 → 1,12 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <libc/stubs.h> |
#include <errno.h> |
#include <sys/stat.h> |
#include <unistd.h> |
#include <libc/dosio.h> |
int mkdir(const char *dirname, mode_t mode) |
{ |
return -1; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/sys/stat/mkfifo.c |
---|
0,0 → 1,10 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <sys/stat.h> |
#include <errno.h> |
int |
mkfifo(const char *path, mode_t mode) |
{ |
errno = EACCES; |
return -1; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/sys/stat/st_loss.c |
---|
0,0 → 1,68 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
/* |
* This is file ST_LOSS.C |
* |
* Function to print a human-readable description of _DJSTAT_FAIL_BITS |
* variable, for debugging purposes. A string which contains description |
* of every fail bit set is printed to the stream given by FP, or to |
* stderr if FP is NULL. |
* |
* Copyright (c) 1994 Eli Zaretskii <eliz@is.elta.co.il> |
* |
* This software may be used freely as long as the above copyright |
* notice is left intact. There is no warranty on this software. |
* |
*/ |
#include <stdio.h> |
#include "xstat.h" |
/* List of messages describing possible failures. There is a message |
for every bit in the _DJSTAT_FAIL_BITS variable, plus a success |
message, which is printed if no bits are set. |
*/ |
static const char *stfail_message[] = { |
"Everything checks out OK", |
"Get DOS SDA call (INT 21h/AX=5D06h/0Dh) failed", |
"Unsupported DOS version: less than 3.10 (for stat), or 1.x (for fstat)", |
"Cannot find SDA entry which corresponds to pathname (bad SDA pointer?)", |
"Get TrueName call (INT 21h/AX=6000h) failed", |
"Failed to get starting cluster number; inode defaults to hashing\n" |
"(if no other messages were printed, then this is either an empty\n" |
"file on a local disk drive, or a file on a networked drive, or\n" |
"you run under some kind of DOS clone)", |
"Root directory has no volume label required to get its time fields", |
"Get SDA call returned preposterously large or negative number of SDAs", |
"Write access bit required, but cannot be figured out", |
"Failed to get drive letter for handle (Novell NetWare 3.x?)", |
"SFT entry found, but is inconsistent with file size and time stamp", |
"Negative index into SFT: might be bad handle table in PSP", |
"File entry not found in SFT array (bad SFT index, or Novell 3.x)" |
}; |
/* Number of used bits we know about in _djstat_fail_bits. */ |
static const int used_bits = sizeof(stfail_message)/sizeof(stfail_message[0]); |
void |
_djstat_describe_lossage(FILE *fp) |
{ |
int i = 0; |
unsigned long bits = _djstat_fail_bits; /* so we don't have side effects */ |
if (fp == 0) |
fp = stderr; /* default: print to stderr */ |
while (bits && i < used_bits) |
{ |
i++; |
if (bits & 1) /* print message for this bit, if set */ |
fprintf(fp, "%s\n", stfail_message[i]); |
bits >>= 1; /* get next bit */ |
} |
/* Did we see any bit set? */ |
if (i == 0) |
fprintf(fp, "%s\n", stfail_message[0]); |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/sys/stat/stat.c |
---|
0,0 → 1,80 |
#include <libc/stubs.h> |
#include <stdlib.h> |
#include <stddef.h> |
#include <unistd.h> |
#include <time.h> |
#include <stdio.h> |
#include <string.h> |
#include <ctype.h> |
#include <errno.h> |
#include <fcntl.h> |
#include <sys/types.h> |
#include <sys/stat.h> |
#include <dos.h> |
#include <dir.h> |
#include <libc/farptrgs.h> |
#include <libc/bss.h> |
#include "xstat.h" |
int stat(const char *path, struct stat *statbuf) |
{ |
int nslash=0; |
const char* p; |
char* q; |
struct systree_info2 finf; |
struct bdfe_item attr; |
memset(statbuf,0,sizeof(*statbuf)); |
// "/<base>/<number>" is special case |
for (p=path;*p;p++) if (*p=='/') ++nslash; |
while (p>path && p[-1]=='/') {--nslash;--p;} |
if (nslash <= 2) |
{ |
statbuf->st_mode = S_IFDIR; |
return 0; |
} |
finf.command = 5; |
finf.file_offset_low = 0; |
finf.file_offset_high = 0; |
finf.size = 0; |
finf.data_pointer = (__u32)&attr; |
_fixpath(path,finf.name); |
for (q=finf.name+strlen(finf.name)-1;q>=finf.name && *q=='/';q--) ; |
q[1]=0; |
if (__kolibri__system_tree_access2(&finf)) |
{ |
errno = EFAULT; |
return -1; |
} |
memset(statbuf,0,sizeof(*statbuf)); |
statbuf->st_size = attr.filesize_low; |
if (attr.attr & 0x10) |
statbuf->st_mode = S_IFDIR; |
struct tm time; |
time.tm_sec = attr.atime.seconds; |
time.tm_min = attr.atime.minutes; |
time.tm_hour = attr.atime.hours; |
time.tm_mday = attr.adate.day; |
time.tm_mon = attr.adate.month; |
time.tm_year = attr.adate.year - 1900; |
time.tm_isdst = -1; |
statbuf->st_atime = mktime(&time); |
time.tm_sec = attr.ctime.seconds; |
time.tm_min = attr.ctime.minutes; |
time.tm_hour = attr.ctime.hours; |
time.tm_mday = attr.cdate.day; |
time.tm_mon = attr.cdate.month; |
time.tm_year = attr.cdate.year - 1900; |
time.tm_isdst = -1; |
statbuf->st_ctime = mktime(&time); |
time.tm_sec = attr.mtime.seconds; |
time.tm_min = attr.mtime.minutes; |
time.tm_hour = attr.mtime.hours; |
time.tm_mday = attr.mdate.day; |
time.tm_mon = attr.mdate.month; |
time.tm_year = attr.mdate.year - 1900; |
time.tm_isdst = -1; |
statbuf->st_mtime = mktime(&time); |
return 0; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/sys/stat/umask.c |
---|
0,0 → 1,11 |
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ |
#include <sys/stat.h> |
mode_t |
umask(mode_t newmask) |
{ |
static mode_t the_mask = 022; |
mode_t old_mask = the_mask; |
the_mask = newmask; |
return old_mask; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/sys/stat/xstat.c |
---|
0,0 → 1,262 |
/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */ |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
/* |
* This is file XSTAT.C |
* |
* Internal assist functions which are common to stat() and fstat(). |
* |
* |
* Copyright (c) 1994-96 Eli Zaretskii <eliz@is.elta.co.il> |
* |
* This software may be used freely as long as the above copyright |
* notice is left intact. There is no warranty on this software. |
* |
*/ |
#include <stdlib.h> |
#include <string.h> |
#include <sys/types.h> |
#include <limits.h> |
#include <time.h> |
#include <errno.h> |
#include <dos.h> |
#include <libc/farptrgs.h> |
#include <libc/dosio.h> |
#include <libc/bss.h> |
#include "xstat.h" |
static int xstat_count = -1; |
/* Some fields of struct stat are expensive to compute under DOS, |
because they require multiple disk accesses. Fortunately, many |
DOS programs don't care about these. To leave both pedants (like |
me) and performance-oriented guys happy, a variable is provided |
which controls which expensive fields should be computed. To get |
the fastest stat() for your program, clear the bits for only those |
features you need and set the others. |
This improvement was suggested by Charles Sandmann |
<sandmann@clio.rice.edu> and DJ Delorie <dj@delorie.com>. */ |
#define _STAT_INODE 1 /* should we bother getting inode numbers? */ |
#define _STAT_EXEC_EXT 2 /* get execute bits from file extension? */ |
#define _STAT_EXEC_MAGIC 4 /* get execute bits from magic signature? */ |
#define _STAT_DIRSIZE 8 /* compute directory size? */ |
#define _STAT_ROOT_TIME 0x10 /* try to get root dir time stamp? */ |
#define _STAT_WRITEBIT 0x20 /* fstat() needs write bit? */ |
/* Should we bother about executables at all? */ |
#define _STAT_EXECBIT (_STAT_EXEC_EXT | _STAT_EXEC_MAGIC) |
/* By default, all the bits are reset (including as yet unused ones), so |
people who don't care will transparently have the full version. */ |
unsigned short _djstat_flags; |
/* As we depend on undocumented DOS features, we could fail in some |
incompatible environment or future DOS versions. If we do, the |
following variable will have some of its bits set. Each bit |
describes a single feature which we tried to use and failed. |
The function _djstat_describe_lossage() may be called to print a |
human-readable description of the bits which were set by the last |
call to f?stat(). This should make debugging f?stat() failures |
in an unanticipated environment a lot easier. |
This improvement was suggested by Charles Sandmann |
<sandmann@clio.rice.edu>. */ |
unsigned short _djstat_fail_bits; |
/* ----------------------------------------------------------------------- */ |
/* Convert file date and time to time_t value suitable for |
struct stat fields. */ |
time_t |
_file_time_stamp(unsigned int dos_ftime) |
{ |
struct tm file_tm; |
memset(&file_tm, 0, sizeof(struct tm)); |
file_tm.tm_isdst = -1; /* let mktime() determine if DST is in effect */ |
file_tm.tm_sec = (dos_ftime & 0x1f) * 2; |
file_tm.tm_min = (dos_ftime >> 5) & 0x3f; |
file_tm.tm_hour = (dos_ftime >> 11) & 0x1f; |
file_tm.tm_mday = (dos_ftime >> 16) & 0x1f; |
file_tm.tm_mon = ((dos_ftime >> 21) & 0x0f) - 1; /* 0 = January */ |
file_tm.tm_year = (dos_ftime >> 25) + 80; |
return mktime(&file_tm); |
} |
/* Get time stamp of a DOS file packed as a 32-bit int. |
* This does what Borland's getftime() does, except it doesn't |
* pollute the application namespace and returns an int instead |
* of struct ftime with packed bit-fields. |
*/ |
int |
_getftime(int fhandle, unsigned int *dos_ftime) |
{ |
return -1; |
} |
/* Invent an inode number for those files which don't have valid DOS |
* cluster number. These could be: devices like /dev/nul; empty |
* files which were not allocated disk space yet; or files on |
* networked drives, for which the redirector doesn't bring the |
* cluster number. |
* |
* To ensure proper operation of this function, you must call it |
* with a filename in some canonical form. E.g., with a name |
* returned by truename(), or that returned by _fixpath(). The |
* point here is that the entire program MUST abide by these |
* conventions through its operation, or else you risk getting |
* different inode numbers for the same file. |
* |
* This function is due to Eric Backus and was taken with minor |
* modifications from stat.c, as included in DJGPP 1.11m5. |
* The function now returns 0 instead of -1 if it can't allocate |
* memory for a new name, so that f?stat() won't fail if the inode |
* is unavailable, but return zero inode instead. |
*/ |
/* |
(c) Copyright 1992 Eric Backus |
This software may be used freely so long as this copyright notice is |
left intact. There is no warranty on this software. |
*/ |
struct name_list |
{ |
struct name_list *next; |
char *name; |
unsigned mtime; |
unsigned long size; |
long inode; |
}; |
ino_t |
_invent_inode(const char *name, unsigned time_stamp, unsigned long fsize) |
{ |
static struct name_list *name_list[256]; |
/* If the st_inode is wider than a short int, we will count up |
* from USHRT_MAX+1 and thus ensure there will be no clashes with |
* actual cluster numbers. |
* Otherwise, we must count downward from USHRT_MAX, which could |
* yield two files with identical inode numbers: one from actual |
* DOS cluster number, and another from this function. In the |
* latter case, we still have at least 80 inode numbers before |
* we step into potentially used numbers, because some FAT entries |
* are reserved to mean EOF, unused entry and other special codes, |
* and the FAT itself uses up some clusters which aren't counted. |
*/ |
static int dir = (sizeof(ino_t) > 2 ? 1 : -1); |
/* INODE_COUNT is declared LONG and not ino_t, because some DOS-based |
* compilers use short or unsigned short for ino_t. |
*/ |
static long inode_count = (sizeof(ino_t) > 2 |
? (long)USHRT_MAX + 1L |
: USHRT_MAX); |
struct name_list *name_ptr, *prev_ptr; |
const char *p; |
int hash; |
/* Force initialization in restarted programs (emacs). */ |
if (xstat_count != __bss_count) |
{ |
xstat_count = __bss_count; |
inode_count = (sizeof(ino_t) > 2 ? (long)USHRT_MAX + 1L : USHRT_MAX); |
memset (name_list, 0, sizeof name_list); |
} |
if (!name) |
return 0; |
/* Skip over device and leading slash. This will allow for less |
* inode numbers to be used, because there is nothing bad in generating |
* identical inode for two files which belong to different drives. |
*/ |
if (*name && name[1] == ':' && (name[2] == '\\' || name[2] == '/')) |
{ |
/* If this is a root directory, return inode = 1. This is compatible |
with the code on stat.c which deals with root directories. */ |
if (name[3] == 0) |
return (ino_t)1; |
name += 3; |
} |
/* If the passed name is empty, invent a new inode unconditionally. |
* This is for those unfortunate circumstances where we couldn't |
* get a name (e.g., fstat() under Novell). For these we want at |
* least to ensure that no two calls will get the same inode number. |
* The lossage here is that you get different inodes even if you call |
* twice with the same file. Sigh... |
*/ |
if (!*name) |
{ |
ino_t retval = inode_count; |
inode_count += dir; |
return retval; |
} |
/* We could probably use a better hash than this */ |
p = name; |
hash = 0; |
while (*p != '\0') |
hash += *p++; |
hash &= 0xff; |
/* Have we seen this string? */ |
name_ptr = name_list[hash]; |
prev_ptr = name_ptr; |
while (name_ptr) |
{ |
if (strcmp(name, name_ptr->name) == 0 && |
name_ptr->mtime == time_stamp && |
name_ptr->size == fsize) |
break; |
prev_ptr = name_ptr; |
name_ptr = name_ptr->next; |
} |
if (name_ptr) |
/* Same string, time stamp, and size, so same inode */ |
return name_ptr->inode; |
else |
{ |
ino_t retval; |
/* New string with same hash code */ |
name_ptr = (struct name_list *)malloc(sizeof *name_ptr); |
if (name_ptr == 0) |
return 0; |
name_ptr->next = (struct name_list *)0; |
name_ptr->name = (char *)malloc(strlen(name)+1); |
if (name_ptr->name == 0) |
{ |
free(name_ptr); |
return 0; |
} |
strcpy(name_ptr->name, name); |
name_ptr->mtime = time_stamp; |
name_ptr->size = fsize; |
name_ptr->inode = inode_count; |
if (prev_ptr) |
prev_ptr->next = name_ptr; |
else |
name_list[hash] = name_ptr; |
retval = inode_count; |
inode_count += dir; /* increment or decrement as appropriate */ |
return retval; |
} |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/sys/stat/xstat.h |
---|
0,0 → 1,72 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
/* |
* Header for internal stat()/fstat() assist functions. |
* |
*/ |
#ifndef __XSTAT_H |
#define __XSTAT_H |
#include <stdio.h> |
#include <time.h> |
#include <sys/types.h> |
#include <sys/stat.h> |
/* Some errno.h headers do not define EFAULT. Here the value is |
taken from POSIX IEEE 1003.1. */ |
#include <errno.h> |
#ifndef EFAULT |
#define EFAULT 14 |
#endif |
/* Under MS-DOS, file access permissions are shared by all, except for |
Write permission. */ |
#define READ_ACCESS (S_IRUSR | S_IRGRP | S_IROTH) |
#define WRITE_ACCESS S_IWUSR |
#define EXEC_ACCESS (S_IXUSR | S_IXGRP | S_IXOTH) |
/* Macro to convert a segment and an offset to a "far offset" suitable |
for _farxxx() functions of DJGPP. */ |
#ifndef MK_FOFF |
#define MK_FOFF(s,o) ((int)((((unsigned long)(s)) << 4) + (unsigned short)(o))) |
#endif |
/* Ralph Brown's Interrupt List says this should be the length |
of the buffer for INT 21H AX=6000H. */ |
#define MAX_TRUE_NAME 128 |
extern unsigned short _osmajor, _osminor; |
extern const char * _os_flavor; |
/* Bits to flag f?stat() failed to use individual undocumented features. */ |
#define _STFAIL_SDA 1 /* Get SDA call failed */ |
#define _STFAIL_OSVER 2 /* Unsupported DOS version */ |
#define _STFAIL_BADSDA 4 /* Bad pointer to SDA */ |
#define _STFAIL_TRUENAME 8 /* _truename() failed */ |
#define _STFAIL_HASH 0x10 /* inode defaults to hashing */ |
#define _STFAIL_LABEL 0x20 /* Root dir, but no volume label */ |
#define _STFAIL_DCOUNT 0x40 /* dirent_count ridiculously large */ |
#define _STFAIL_WRITEBIT 0x80 /* fstat() failed to get write access bit */ |
#define _STFAIL_DEVNO 0x100 /* fstat() failed to get device number */ |
#define _STFAIL_BADSFT 0x200 /* SFT entry found, but can't be trusted */ |
#define _STFAIL_SFTIDX 0x400 /* bad SFT index in JFT */ |
#define _STFAIL_SFTNF 0x800 /* file entry not found in SFT array */ |
extern unsigned short _djstat_fail_bits; |
extern unsigned short _djstat_flags; |
extern time_t _file_time_stamp(unsigned int); |
extern ino_t _invent_inode(const char *, unsigned, unsigned long); |
extern unsigned short _get_magic(const char *, int); |
extern unsigned short _get_dos_version(int); |
extern char * _truename(const char *, char *); |
extern int _is_remote_drive(int); |
extern int _is_executable(const char *, int, const char *); |
extern short _get_dev_info(int); |
extern long __filelength(int); |
extern int _is_remote_handle(int); |
extern void _djstat_describe_lossage(FILE *); |
extern int _getftime(int, unsigned int *); |
#endif /* __XSTAT_H */ |
/programs/develop/libraries/menuetlibc/src/libc/posix/sys/times/Makefile |
---|
0,0 → 1,3 |
THIS_SRCS = times.c |
include $(MENUET_LIBC_TOPDIR)/Make.rules |
/programs/develop/libraries/menuetlibc/src/libc/posix/sys/times/times.c |
---|
0,0 → 1,19 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <errno.h> |
#include <sys/times.h> |
#include <time.h> |
clock_t |
times(struct tms *buffer) |
{ |
if (buffer == 0) |
{ |
errno = EINVAL; |
return (clock_t)(-1); |
} |
buffer->tms_utime = clock(); |
buffer->tms_stime = 0; |
buffer->tms_cutime = 0; |
buffer->tms_cstime = 0; |
return buffer->tms_utime; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/sys/wait/Makefile |
---|
0,0 → 1,3 |
THIS_SRCS = wait.c waitpid.c |
include $(MENUET_LIBC_TOPDIR)/Make.rules |
/programs/develop/libraries/menuetlibc/src/libc/posix/sys/wait/wait.c |
---|
0,0 → 1,11 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <sys/wait.h> |
#include <errno.h> |
/* ARGSUSED */ |
pid_t |
wait(int *stat_loc) |
{ |
errno = ECHILD; |
return -1; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/sys/wait/waitpid.c |
---|
0,0 → 1,11 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <sys/wait.h> |
#include <errno.h> |
/* ARGSUSED */ |
pid_t |
waitpid(pid_t pid, int *stat_loc, int options) |
{ |
errno = ECHILD; |
return -1; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/Makefile |
---|
0,0 → 1,8 |
THIS_SRCS = access.c alarm.c chdir.c chown.c close.c ctermid.c dup2.c \ |
dup.c execl.c execle.c execlp.c execlpe.c execv.c execve.c execvp.c \ |
execvpe.c fork.c fpathcon.c getcwd.c getegid.c geteuid.c getgid.c \ |
getgroup.c getlogin.c getopt.c getpgrp.c getpid.c getppid.c getuid.c \ |
isatty.c link.c lseek.c pathconf.c pause.c pipe.c read.c rmdir.c setgid.c \ |
setpgid.c setsid.c setuid.c sleep.c sysconf.c ttyname.c unlink.s write.c |
include $(MENUET_LIBC_TOPDIR)/Make.rules |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/access.c |
---|
0,0 → 1,59 |
/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */ |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <libc/stubs.h> |
#include <unistd.h> |
#include <stdio.h> |
#include <sys/stat.h> |
#include <io.h> |
#include <dirent.h> |
#include <errno.h> |
int access(const char *fn, int flags) |
{ |
unsigned attr = _chmod(fn, 0); |
if (attr == -1) { |
char fixed_path[FILENAME_MAX]; |
const char* p; |
int nums = 0; |
DIR* d; |
/* Root directories on some non-local drives (e.g. CD-ROM) |
might fail `_chmod'. `findfirst' to the rescue. */ |
_fixpath(fn, fixed_path); |
for (p=fixed_path;*p;p++) if (*p == '/') ++nums; |
if (nums <= 2) |
{ |
d = opendir(fn); |
if (d) {closedir(d);return 0;} |
} |
errno = ENOENT; |
return -1; |
} |
if (attr & 0x10) /* directory? */ |
return 0; /* directories always OK */ |
if (flags & D_OK) |
{ |
errno = EACCES; |
return -1; /* not a directory */ |
} |
if ((flags & W_OK) && (attr & 1)) |
{ |
errno = EACCES; |
return -1; /* not writable */ |
} |
if (flags & X_OK) |
{ |
if (!_is_executable(fn, 0, 0)) |
{ |
errno = EACCES; |
return -1; |
} |
} |
return 0; /* everything else is OK */ |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/alarm.c |
---|
0,0 → 1,12 |
/* Copyright (C) 1995 Charles Sandmann (sandmann@clio.rice.edu) |
alarm() implmentation using setitimer |
This software may be freely distributed, no warranty. */ |
#include <libc/stubs.h> |
#include <unistd.h> |
#include <sys/time.h> |
unsigned int alarm(unsigned int seconds) |
{ |
return seconds; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/chdir.c |
---|
0,0 → 1,14 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <libc/stubs.h> |
#include <unistd.h> |
#include <errno.h> |
#include <ctype.h> |
#include <libc/dosio.h> |
void __chdir(char * path); |
int chdir (const char *dirname) |
{ |
__chdir((char *)dirname); |
return 0; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/chown.c |
---|
0,0 → 1,15 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <libc/stubs.h> |
#include <unistd.h> |
#include <sys/stat.h> |
#include <errno.h> |
/* MS-DOS couldn't care less about file ownerships, so we could |
always succeed. At least fail for non-existent files |
and for devices. */ |
int chown(const char *path, uid_t owner, gid_t group) |
{ |
errno = ENOENT; |
return -1; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/close.c |
---|
0,0 → 1,6 |
#include<menuet/os.h> |
int close(int handle) |
{ |
return dosemu_close(handle); |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/ctermid.c |
---|
0,0 → 1,14 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <unistd.h> |
#include <string.h> |
static char def_termid[] = "con"; |
char * |
ctermid(char *_s) |
{ |
if (!_s) |
return def_termid; |
strcpy(_s, def_termid); |
return _s; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/dup.c |
---|
0,0 → 1,11 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <libc/stubs.h> |
#include <unistd.h> |
#include <errno.h> |
#include <io.h> |
#include <libc/dosio.h> |
int dup(int fd) |
{ |
return -1; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/dup2.c |
---|
0,0 → 1,12 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <libc/stubs.h> |
#include <unistd.h> |
#include <errno.h> |
#include <io.h> |
#include <libc/dosio.h> |
int |
dup2(int fd, int newfd) |
{ |
return -1; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/execl.c |
---|
0,0 → 1,11 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <libc/stubs.h> |
#include <unistd.h> |
#include <process.h> |
extern char *const *environ; |
int execl(const char *path, const char *argv0, ...) |
{ |
return spawnve(P_OVERLAY, path, (char *const*)&argv0, environ); |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/execle.c |
---|
0,0 → 1,11 |
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ |
#include <libc/stubs.h> |
#include <unistd.h> |
#include <process.h> |
#include <libc/dosexec.h> |
int execle(const char *path, const char *argv0, ... /*, const char **envp */) |
{ |
scan_ptr(); |
return spawnve(P_OVERLAY, path, (char *const *)&argv0, (char *const *)ptr); |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/execlp.c |
---|
0,0 → 1,12 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <libc/stubs.h> |
#include <unistd.h> |
#include <process.h> |
#include <libc/dosexec.h> |
extern char * const *environ; |
int execlp(const char *path, const char *argv0, ...) |
{ |
return spawnvpe(P_OVERLAY, path, (char * const *)&argv0, environ); |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/execlpe.c |
---|
0,0 → 1,11 |
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ |
#include <libc/stubs.h> |
#include <unistd.h> |
#include <process.h> |
#include <libc/dosexec.h> |
int execlpe(const char *path, const char *argv0, ... /*, const char **envp */) |
{ |
scan_ptr(); |
return spawnvpe(P_OVERLAY, path, (char * const *)&argv0, (char * const *)ptr); |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/execv.c |
---|
0,0 → 1,11 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <libc/stubs.h> |
#include <unistd.h> |
#include <process.h> |
extern char * const *environ; |
int execv(const char *path, char * const *argv) |
{ |
return spawnve(P_OVERLAY, path, argv, environ); |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/execve.c |
---|
0,0 → 1,9 |
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ |
#include <libc/stubs.h> |
#include <unistd.h> |
#include <process.h> |
int execve(const char *path, char * const argv[], char * const envp[]) |
{ |
return spawnve(P_OVERLAY, path, argv, envp); |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/execvp.c |
---|
0,0 → 1,11 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <libc/stubs.h> |
#include <unistd.h> |
#include <process.h> |
extern char *const *environ; |
int execvp(const char *path, char * const argv[]) |
{ |
return spawnvpe(P_OVERLAY, path, argv, environ); |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/execvpe.c |
---|
0,0 → 1,9 |
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ |
#include <libc/stubs.h> |
#include <unistd.h> |
#include <process.h> |
int execvpe(const char *path, char * const argv[], char * const envp[]) |
{ |
return spawnvpe(P_OVERLAY, path, argv, envp); |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/fork.c |
---|
0,0 → 1,9 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <errno.h> |
#include <unistd.h> |
pid_t fork(void) |
{ |
errno = ENOMEM; /* The only other choice is EAGAIN, and we don't want that */ |
return -1; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/fpathcon.c |
---|
0,0 → 1,10 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <errno.h> |
#include <unistd.h> |
#include <limits.h> |
/* ARGSUSED */ |
long fpathconf(int fildes, int name) |
{ |
return pathconf("/", name); |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/getcwd.c |
---|
0,0 → 1,27 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <libc/stubs.h> |
#include <unistd.h> |
#include <stdlib.h> |
#include <errno.h> |
#include <libc/farptrgs.h> |
#include <libc/dosio.h> |
static char * __cur_cwd; |
extern char* __get_curdir(void); |
char * getcwd(char *buf, size_t size) |
{ |
#ifndef min |
#define min(a,b) ((a)<(b)?(a):(b)) |
#endif |
size_t k; |
__cur_cwd=__get_curdir(); |
k=min(size,strlen(__cur_cwd)); |
memcpy(buf,__cur_cwd,k+1); |
return buf; |
} |
void __libc_set_cwd(char * p) |
{ |
__chdir(p); |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/getegid.c |
---|
0,0 → 1,9 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <unistd.h> |
gid_t |
getegid(void) |
{ |
return 42; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/geteuid.c |
---|
0,0 → 1,8 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <unistd.h> |
uid_t |
geteuid(void) |
{ |
return 42; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/getgid.c |
---|
0,0 → 1,8 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <unistd.h> |
gid_t getgid(void) |
{ |
return 42; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/getgroup.c |
---|
0,0 → 1,9 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <unistd.h> |
/* ARGSUSED */ |
int |
getgroups(int _size, gid_t *grouplist) |
{ |
return 0; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/getlogin.c |
---|
0,0 → 1,8 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <unistd.h> |
#include <stdlib.h> |
char * getlogin(void) |
{ |
return "root"; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/getopt.c |
---|
0,0 → 1,85 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <libc/stubs.h> |
#include <stdio.h> |
#include <string.h> |
#include <unistd.h> |
#include <libc/unconst.h> |
int opterr = 1, optind = 1, optopt = 0; |
char *optarg = 0; |
#define BADCH (int)'?' |
#define EMSG "" |
int |
getopt(int nargc, char *const nargv[], const char *ostr) |
{ |
static const char *place = EMSG; /* option letter processing */ |
char *oli; /* option letter list index */ |
char *p; |
if (!*place) |
{ |
if (optind >= nargc || *(place = nargv[optind]) != '-') |
{ |
place = EMSG; |
return(EOF); |
} |
if (place[1] && *++place == '-') |
{ |
++optind; |
place = EMSG; |
return(EOF); |
} |
} |
if ((optopt = (int)*place++) == (int)':' |
|| !(oli = strchr(ostr, optopt))) |
{ |
/* |
* if the user didn't specify '-' as an option, |
* assume it means EOF. |
*/ |
if (optopt == (int)'-') |
return EOF; |
if (!*place) |
++optind; |
if (opterr) |
{ |
if (!(p = strrchr(*nargv, '/'))) |
p = *nargv; |
else |
++p; |
fprintf(stderr, "%s: illegal option -- %c\n", p, optopt); |
} |
return BADCH; |
} |
if (*++oli != ':') |
{ /* don't need argument */ |
optarg = NULL; |
if (!*place) |
++optind; |
} |
else |
{ /* need an argument */ |
if (*place) /* no white space */ |
optarg = unconst(place, char *); |
else if (nargc <= ++optind) |
{ /* no arg */ |
place = EMSG; |
if (!(p = strrchr(*nargv, '/'))) |
p = *nargv; |
else |
++p; |
if (opterr) |
fprintf(stderr, "%s: option requires an argument -- %c\n", |
p, optopt); |
return BADCH; |
} |
else /* white space */ |
optarg = nargv[optind]; |
place = EMSG; |
++optind; |
} |
return optopt; /* dump back option letter */ |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/getpgrp.c |
---|
0,0 → 1,8 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <unistd.h> |
pid_t |
getpgrp(void) |
{ |
return getpid(); |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/getpid.c |
---|
0,0 → 1,17 |
/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */ |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <unistd.h> |
#include <libc/farptrgs.h> |
#include <libc/bss.h> |
#include <menuet/os.h> |
static int pid_count = -1; |
static pid_t my_pid; |
static struct process_table_entry __tmp_proctab; |
pid_t getpid(void) |
{ |
__menuet__get_process_table(&__tmp_proctab,PID_WHOAMI); |
return __tmp_proctab.pid; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/getppid.c |
---|
0,0 → 1,7 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <unistd.h> |
pid_t getppid(void) |
{ |
return 1; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/getuid.c |
---|
0,0 → 1,7 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <unistd.h> |
uid_t getuid(void) |
{ |
return 42; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/isatty.c |
---|
0,0 → 1,9 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <libc/stubs.h> |
#include <unistd.h> |
int isatty(int fd) |
{ |
if(fd==0 || fd==1) return 1; |
return 0; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/link.c |
---|
0,0 → 1,13 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <libc/stubs.h> |
#include <sys/stat.h> /* For stat() */ |
#include <fcntl.h> /* For O_RDONLY, etc. */ |
#include <unistd.h> /* For read(), write(), etc. */ |
#include <limits.h> /* For PATH_MAX */ |
#include <utime.h> /* For utime() */ |
#include <errno.h> /* For errno */ |
int link(const char *path1, const char *path2) |
{ |
return -1; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/lseek.c |
---|
0,0 → 1,9 |
#include <unistd.h> |
#include <errno.h> |
#include <libc/dosio.h> |
off_t lseek(int handle, off_t offset, int whence) |
{ |
return dosemu_lseek(handle,offset,whence); |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/pathconf.c |
---|
0,0 → 1,25 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <errno.h> |
#include <unistd.h> |
#include <limits.h> |
long |
pathconf(const char *path, int name) |
{ |
switch (name) |
{ |
case _PC_LINK_MAX: return LINK_MAX; |
case _PC_MAX_CANON: return MAX_CANON; |
case _PC_MAX_INPUT: return MAX_INPUT; |
case _PC_NAME_MAX: return NAME_MAX; |
case _PC_PATH_MAX: return PATH_MAX; |
case _PC_PIPE_BUF: return PIPE_BUF; |
case _PC_CHOWN_RESTRICTED: return _POSIX_CHOWN_RESTRICTED; |
case _PC_NO_TRUNC: return _POSIX_NO_TRUNC; |
case _PC_VDISABLE: return _POSIX_VDISABLE; |
default: |
errno = EINVAL; |
return -1; |
} |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/pause.c |
---|
0,0 → 1,8 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <unistd.h> |
int pause(void) |
{ |
__menuet__delay100(1); |
return 0; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/pipe.c |
---|
0,0 → 1,10 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <unistd.h> |
#include <errno.h> |
int |
pipe(int _fildes[2]) |
{ |
errno = EACCES; |
return -1; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/read.c |
---|
0,0 → 1,11 |
#include <stdlib.h> |
#include <fcntl.h> |
#include <unistd.h> |
#include <io.h> |
#include <libc/dosio.h> |
ssize_t read(int handle, void* buffer, size_t count) |
{ |
return dosemu_read(handle,buffer,count); |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/rmdir.c |
---|
0,0 → 1,11 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <libc/stubs.h> |
#include <errno.h> |
#include <unistd.h> |
#include <libc/dosio.h> |
int |
rmdir(const char *dirname) |
{ |
return 0; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/setgid.c |
---|
0,0 → 1,14 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <unistd.h> |
#include <errno.h> |
int |
setgid(gid_t _gid) |
{ |
if (_gid != getgid()) |
{ |
errno = EPERM; |
return -1; |
} |
return 0; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/setpgid.c |
---|
0,0 → 1,15 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <unistd.h> |
#include <errno.h> |
/* ARGSUSED */ |
int |
setpgid(pid_t _pid, pid_t _pgid) |
{ |
if (_pgid != getpid()) |
{ |
errno = EPERM; |
return -1; |
} |
return 0; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/setsid.c |
---|
0,0 → 1,9 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <unistd.h> |
#include <errno.h> |
pid_t |
setsid(void) |
{ |
return getpid(); |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/setuid.c |
---|
0,0 → 1,12 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <unistd.h> |
#include <errno.h> |
int |
setuid(uid_t uid) |
{ |
if (uid == getuid()) |
return 0; |
errno = EPERM; |
return -1; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/sleep.c |
---|
0,0 → 1,10 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <unistd.h> |
#include <time.h> |
#include <menuet/os.h> |
unsigned int sleep(unsigned int _seconds) |
{ |
for(;_seconds;_seconds--) __menuet__delay100(100); |
return _seconds; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/sysconf.c |
---|
0,0 → 1,29 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <errno.h> |
#include <unistd.h> |
#include <limits.h> |
#include <time.h> |
#include <stdio.h> |
#include <fcntl.h> |
long |
sysconf(int name) |
{ |
switch (name) |
{ |
case _SC_ARG_MAX: return ARG_MAX; |
case _SC_CHILD_MAX: return CHILD_MAX; |
case _SC_CLK_TCK: return CLOCKS_PER_SEC; |
case _SC_NGROUPS_MAX: return NGROUPS_MAX; |
case _SC_OPEN_MAX: return 255; |
case _SC_JOB_CONTROL: return -1; |
case _SC_SAVED_IDS: return -1; |
case _SC_STREAM_MAX: return _POSIX_STREAM_MAX; |
case _SC_TZNAME_MAX: return TZNAME_MAX; |
case _SC_VERSION: return _POSIX_VERSION; |
default: |
errno = EINVAL; |
return -1; |
} |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/ttyname.c |
---|
0,0 → 1,15 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <libc/stubs.h> |
#include <unistd.h> |
static char dev_con[] = "con"; |
/* ARGSUSED */ |
char * |
ttyname(int fildes) |
{ |
if (isatty(fildes)) |
return dev_con; |
else |
return 0; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/unlink.s |
---|
0,0 → 1,5 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include<libc/asm.h> |
MK_C_SYM(unlink) |
jmp C_SYM(remove) |
/programs/develop/libraries/menuetlibc/src/libc/posix/unistd/write.c |
---|
0,0 → 1,22 |
#include <unistd.h> |
#include <stdlib.h> |
#include <string.h> |
#include <fcntl.h> |
#include <io.h> |
#include <errno.h> |
#include <libc/dosio.h> |
#include <libc/bss.h> |
#include<menuet/os.h> |
#include<menuet/console.h> |
static char *sbuf = 0; |
static size_t sbuflen = 0; |
static int write_count = -1; |
ssize_t write(int handle, const void* buffer, size_t count) |
{ |
return dosemu_write(handle,buffer,count); |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/utime/Makefile |
---|
0,0 → 1,3 |
THIS_SRCS = utime.c |
include $(MENUET_LIBC_TOPDIR)/Make.rules |
/programs/develop/libraries/menuetlibc/src/libc/posix/utime/utime.c |
---|
0,0 → 1,16 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <libc/stubs.h> |
#include <utime.h> /* For utime() */ |
#include <time.h> /* For localtime() */ |
#include <fcntl.h> /* For open() */ |
#include <unistd.h> |
#include <errno.h> /* For errno */ |
/* An implementation of utime() for DJGPP. The utime() function |
specifies an access time and a modification time. DOS has only one |
time, so we will (arbitrarily) use the modification time. */ |
int |
utime(const char *path, const struct utimbuf *times) |
{ |
return 0; |
} |
/programs/develop/libraries/menuetlibc/src/libc/posix/utsname/Makefile |
---|
0,0 → 1,3 |
THIS_SRCS = uname.c |
include $(MENUET_LIBC_TOPDIR)/Make.rules |
/programs/develop/libraries/menuetlibc/src/libc/posix/utsname/uname.c |
---|
0,0 → 1,18 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <libc/stubs.h> |
#include <stdio.h> |
#include <string.h> |
#include <sys/utsname.h> |
#include <errno.h> |
#include <dos.h> |
int uname(struct utsname *u) |
{ |
strncpy(u->sysname, "MenuetOS",8); |
u->sysname[sizeof(u->sysname) - 1] = '\0'; |
sprintf(u->version, "0.47"); |
sprintf(u->release, "1.0"); |
strcpy(u->machine, "i386"); |
strcpy(u->nodename, "(none)"); |
return 0; |
} |