提交 317ea8bf 编写于 作者: B Bruce Momjian

Remove win32 port directory. Forgot to do it earlier.

上级 7a14979f
#include <windows.h>
#include <time.h>
#include "postgres.h"
#include "storage/ipc.h"
/* The name of the Postgres 95 ipc file mapping object */
#define IPC_NAME "PG95_IPC"
/* The name of the Postgres 95 ipc file mapping object semaphore */
#define IPC_SEM_NAME "PG95_IPC_SEM"
/* The maximum length of a shared memory object name */
#define IPC_MAX_SHMEM_NAME 32
/* The maximum number of emulated Unix shared memory segments */
#define IPC_NMAXSHM 10
/* The Maximum number of elements in a semaphore set. Note that this
** is just a guess.
*/
#define IPC_NMAXSEMGRP 7
/* The various states of a semaphore */
#define SIGNALED 1
#define UNSIGNALED 0
#define UNUSED -1
/* The security attribute structure necessary for handles to be inhereted */
SECURITY_ATTRIBUTES sec_attrib = { sizeof (LPSECURITY_ATTRIBUTES),
NULL, TRUE};
/*
Postgres95 uses semaphores and shared memory. Both are provided by
Unix and NT, although NT uses a different method for referencing
them. Rather than changing the function calls used by Postgres95
to use NT system services, we've written code to emulate the Unix
system calls. We deliberately don't do a complete emulation of the
Unix calls, partly because it doesn't appear possible, but also
because only a few options of the Unix calls are actually used by
Postgres95.
The most noticable difference between the way Unix and NT use semaphores
is that the central entity on Unix is a semaphore set consisting of
potientially many actual semaphores whereas on NT a semaphore handle
represents just one actual semaphore. Furthermore, a Unix semaphore set
is identified by one semaphore id no matter how many elements there
are in the set. Given a Unix semaphore id, the Unix API provides a way
to index into the set to reference a specific semaphore.
You might think that since both a semaphore id and a semaphore handle
is just an integer there won't be any changes necessary to the Postgres95
code to deal with NT semaphores. If it weren't for the existence of
multi-semaphore semaphore sets this would be true.
To handle semaphore sets a fixed-size table, whose size is partially
based on the sum of the maximum number of semaphores times the maximum
number of semaphores per semaphore set, is created and kept in shared
memory that is visable to every backend started by the Postmaster.
Each semaphore set entry consists of an arbitrary key value, which serves
to identify the semaphore set, and IPC_NMAXSEMGRP array elements to
store the NT semaphore handles representing the NT semaphore used for
the semaphore set. Semaphore IDs are just indices into this table.
In order to distinguish occupied entries in this table -1 is always
considered an invalid semaphore ID.
This table is also used to store information about shared memory
segments. Fortunately, there is a one-to-one mapping between Unix
shared memory IDs and NT shared memory handles so the code to emulate
Unix shared memory is simple.
*/
/* We need one of these for each emulated semaphore set */
struct Pg_sem
{
key_t Pg_sem_key;
HANDLE Pg_sem_handle[IPC_NMAXSEMGRP];
int Pg_sem_nsems;
};
/* We need one of these for each emulated shared memory segment */
struct Pg_shm
{
key_t Pg_shm_key;
HANDLE Pg_shm_handle;
};
/* This structure is what's stored in shared memory. Note that
** since both the shared memory and semaphore data is in the same
** table, and the table is protected by a single NT semaphore, there's
** a chance that semaphore manipulation could be slowed down by
** shared memory manipulation, and vice versa. But, since both are
** allocated primarily when the Postmaster starts up, which isn't time
** critical, I don't think this will prove to be a problem.
*/
static struct Pg_shared
{
int Pg_next_sem;
int Pg_next_shm;
struct Pg_sem Pg_sem[IPC_NMAXSEM];
struct Pg_shm Pg_shm[IPC_NMAXSHM];
} *Pg_shared_ptr;
/* The semaphore that protects the shared memory table */
HANDLE Pg_shared_hnd;
/*
** Perform a semaphore operation. We're passed a semaphore set id,
** a pointer to an array of sembuf structures, and the number
** of elements in the array. Each element in the sembuf structure
** describes a specific semaphore within the semaphore set and the
** operation to perform on it.
*/
int
semop(int semid, struct sembuf *sops, u_int nsops)
{
u_int i;
int result;
HANDLE hndl;
/* Go through all the sops structures */
for (i = 0; i < nsops; i++)
{
struct sembuf *sptr;
int semval;
int av_sem_op;
sptr = &sops[i];
/*
printf("performing %d in sem # %d\n", sptr->sem_op, sptr->sem_num);
*/
/*
** Postgres95 uses -255 to represent a lock request
** and 255 to show a lock release. Changing these values
** to -1 and 1 make it easier to keep track of the state
** of the semaphore.
*/
if (sptr->sem_op == -255)
sptr->sem_op = -1;
else if (sptr->sem_op == 255)
sptr->sem_op = 1;
else
printf("invalid sem_op %d\n", sptr->sem_op);
_get_ipc_sem();
hndl = Pg_shared_ptr->Pg_sem[semid].Pg_sem_handle[sptr->sem_num];
_rel_ipc_sem();
semval = _get_sem_val(hndl);
if (sptr->sem_op == 0)
{
if (semval == UNSIGNALED)
return(semval);
else
{
if (sptr->sem_flg & IPC_NOWAIT)
return(SIGNALED);
else
result = WaitForSingleObject(hndl, 5000);
}
}
av_sem_op = abs(sptr->sem_op);
/* If a lock is being attempted */
if (sptr->sem_op < 0)
{
if (semval >= av_sem_op)
{
semval -= av_sem_op;
if (semval <= UNSIGNALED)
result = WaitForSingleObject(hndl, 5000);
}
else
{
if (sptr->sem_flg & IPC_NOWAIT)
return(SIGNALED);
else
result = WaitForSingleObject(hndl, 5000);
}
}
/* If a lock is being released */
if (sptr->sem_op > 0)
{
semval += av_sem_op;
if (semval > 0)
ReleaseSemaphore(hndl, 1, NULL);
}
}
}
int
semget(key_t key, int nsems, int semflg)
{
int id, new_sem, ret_val;
/* If nmsems is 0 then assume that we're just checking whether
** the semaphore identified by key exists. Assume that
** if key is IPC_PRIVATE that this should always fail.
*/
if (nsems == 0)
{
if (key == IPC_PRIVATE)
ret_val = -1;
else
{
_get_ipc_sem();
id = _get_sem_id(key);
_rel_ipc_sem();
ret_val = id;
}
return(ret_val);
}
/* See if there's already a semaphore with the key.
** If not, record the key, allocate enough space for the
** handles of the semaphores, and then create the semaphores.
*/
_get_ipc_sem();
id = _get_sem_id(key);
if (id == UNUSED)
{
register int i;
struct Pg_sem *pg_ptr;
new_sem = Pg_shared_ptr->Pg_next_sem++;
pg_ptr = &(Pg_shared_ptr->Pg_sem[new_sem]);
pg_ptr->Pg_sem_key = key;
pg_ptr->Pg_sem_nsems = nsems;
for (i = 0; i < nsems; i++)
pg_ptr->Pg_sem_handle[i] = CreateSemaphore(&sec_attrib, 1, 255, NULL);
ret_val = new_sem;
}
else
ret_val = id;
_rel_ipc_sem();
return(ret_val);
}
/* These next two functions could be written as one function, although
** doing so would require some additional logic.
*/
/* Given a semaphore key, return the corresponding id.
** This function assumes that the shared memory table is being
** protected by the shared memory table semaphore.
*/
_get_sem_id(key_t key)
{
register int i;
/* Go through the shared memory table looking for a semaphore
** whose key matches what we're looking for
*/
for (i = 0; i < Pg_shared_ptr->Pg_next_sem; i++)
if (Pg_shared_ptr->Pg_sem[i].Pg_sem_key == key)
return(i);
/* Return UNUSED if we didn't find a match */
return(UNUSED);
}
/* Given a shared memory key, return the corresponding id
** This function assumes that the shared memory table is being
** protected by the shared memory table semaphore.
*/
_get_shm_id(key_t key)
{
register int i;
/* Go through the shared memory table looking for a semaphore
** whose key matches what we're looking for
*/
for (i = 0; i < Pg_shared_ptr->Pg_next_shm; i++)
if (Pg_shared_ptr->Pg_shm[i].Pg_shm_key == key)
return(i);
/* Return UNUSED if we didn't find a match */
return(UNUSED);
}
int
semctl(int semid, int semnum, int cmd, void *y)
{
int old_val;
HANDLE hndl;
switch (cmd)
{
case SETALL:
case SETVAL:
/* We can't change the value of a semaphore under
** NT except by releasing it or waiting for it.
*/
return(0);
case GETVAL:
_get_ipc_sem();
hndl = Pg_shared_ptr->Pg_sem[semid].Pg_sem_handle[semnum];
_rel_ipc_sem();
old_val = _get_sem_val(hndl);
return(old_val);
}
}
/* Get the current value of the semaphore whose handle is passed in hnd
** This function does NOT assume that the shared memory table is being
** protected by the shared memory table semaphore.
*/
int
_get_sem_val(HANDLE hnd)
{
DWORD waitresult;
/* Try to get the semaphore */
waitresult = WaitForSingleObject(hnd, 0L);
/* Check what the value of the semaphore was */
switch(waitresult)
{
/* The semaphore was signaled so we just got it.
** Since we don't really want to keep it, since we just
** wanted to test its value, go ahead and release it.
*/
case WAIT_OBJECT_0:
ReleaseSemaphore(hnd, 1, NULL);
return(SIGNALED);
/* The semaphore was non-signaled meaning someone else had it. */
case WAIT_TIMEOUT:
return(UNSIGNALED);
}
}
int
shmget(key_t key, uint32 size, int flags)
{
HANDLE hnd;
char name[IPC_MAX_SHMEM_NAME];
int id;
/* Get the handle for the key, if any. */
_get_ipc_sem();
id = _get_shm_id(key);
_rel_ipc_sem();
/* If we're really going to create a new mapping */
if (flags != 0)
{
/* if the key is already being used return an error */
if (id != UNUSED)
return(-1);
/* convert the key to a character string */
sprintf(name, "%d", key);
hnd = CreateFileMapping((HANDLE)0xffffffff,
&sec_attrib, PAGE_READWRITE,
0, size, name);
if (hnd == NULL)
return(-1);
else
{
int new_ipc;
struct Pg_shm *pg_ptr;
_get_ipc_sem();
new_ipc = Pg_shared_ptr->Pg_next_shm++;
pg_ptr = &(Pg_shared_ptr->Pg_shm[new_ipc]);
pg_ptr->Pg_shm_key = key;
pg_ptr->Pg_shm_handle = hnd;
_rel_ipc_sem();
return(new_ipc);
}
}
/* flags is 0 so we just want the id for the existing mapping */
else
return(id);
}
shmdt(char *shmaddr)
{
UnmapViewOfFile(shmaddr);
}
int
shmctl(IpcMemoryId shmid, int cmd, struct shmid_ds *buf)
{
int x = 0;
if (cmd == IPC_RMID)
{
_get_ipc_sem();
CloseHandle(Pg_shared_ptr->Pg_shm[shmid].Pg_shm_handle);
_rel_ipc_sem();
return(0);
}
x = x / x;
}
/* Attach to the already created shared memory segment */
LPVOID *
shmat(int shmid, void *shmaddr, int shmflg)
{
LPVOID *ret_addr;
_get_ipc_sem();
ret_addr = MapViewOfFile(Pg_shared_ptr->Pg_shm[shmid].Pg_shm_handle,
FILE_MAP_ALL_ACCESS, 0, 0, 0);
_rel_ipc_sem();
if (ret_addr == NULL)
{
int jon;
jon = GetLastError();
}
return(ret_addr);
}
/* This is the function that is called when the postmaster starts up.
** It is here that the shared memory table is created. Also, create
** the semaphore that will be used to protect the shared memory table.
** TODO - do something with the return value.
*/
_nt_init()
{
HANDLE hnd;
int size = sizeof (struct Pg_shared);
/* Create the file mapping for the shared memory to be
** used to store the ipc table.
*/
hnd = CreateFileMapping((HANDLE)0xffffffff,
&sec_attrib, PAGE_READWRITE,
0, size, IPC_NAME);
if (hnd == NULL)
{
size = GetLastError();
return(-1);
}
Pg_shared_hnd = CreateSemaphore(&sec_attrib, 1, 255, IPC_SEM_NAME);
if (Pg_shared_hnd == NULL)
{
size = GetLastError();
return(-1);
}
}
/* This function gets called by every backend at startup time. Its
** main duty is to put the address of the shared memory table pointed
** to by Pg_shared_ptr. There's no need to get the IPC_SEM_NAME semaphore
** because this function is called before we start manipulating the
** shared memory table.
*/
void
_nt_attach()
{
HANDLE hnd;
/* Get a handle to the shared memory table */
hnd = OpenFileMapping(FILE_MAP_ALL_ACCESS,
FALSE, IPC_NAME);
/* Map the ipc shared memory table into the address space
** of this process at an address returned by MapViewOfFile
*/
Pg_shared_ptr = (struct Pg_shared *) MapViewOfFile(hnd,
FILE_MAP_ALL_ACCESS, 0, 0, 0);
if (Pg_shared_ptr == NULL)
{
hnd = GetLastError();
return(-1);
}
}
_get_ipc_sem()
{
WaitForSingleObject(Pg_shared_hnd, 5000);
}
_rel_ipc_sem()
{
ReleaseSemaphore(Pg_shared_hnd, 1, NULL);
}
pg_dlerror(void)
{
int x = 0;
x = x / x;
}
pg_dlclose(void *handle)
{
FreeLibrary(handle);
}
void *
pg_dlopen(char *filename)
{
HINSTANCE hinstlib;
hinstlib = LoadLibrary(filename);
return (hinstlib);
}
void *
pg_dlsym(void *handle, char *funcname)
{
void *proc;
proc = GetProcAddress(handle, funcname);
return (proc);
}
void
ftruncate(int fd, int offset)
{
HANDLE hnd;
_lseek(fd, offset, SEEK_SET);
hnd = _get_osfhandle(fd);
SetEndOfFile(hnd);
}
/* The rest are just stubs that are intended to serve as place holders
** in case we want to set breakpoints to see what's happening when
** these routines are called. They'll eventually have to be filled
** in but they're not necessary to get Postgres95 going.
*/
setuid(int i)
{
int x = 1;
x = x / x;
}
setsid()
{
int x = 1;
x = x / x;
}
vfork(void)
{
int x = 0;
x = x / x;
}
ttyname(int y)
{
int x = 0;
x = x / x;
}
step(char *string, char *expbuf)
{
int x = 0;
x = x / x;
}
siglongjmp(int env, int value)
{
int x = 0;
x = x / x;
}
pause(void)
{
int x = 0;
x = x / x;
}
kill(int process, int signal)
{
int x = 1;
x = x / x;
}
getuid(void)
{
int x = 1;
x = x / x;
}
geteuid( void )
{
int x = 1;
x = x / x;
}
int
fsync(int filedes)
{
}
fork(void)
{
int x = 0;
x = x / x;
}
char *
compile(char *instring,char *expbuf,char *endbuf,int eof)
{
int x = 0;
x = x / x;
}
beginRecipe(char *s)
{
int x = 0;
x = x / x;
}
typedef char * caddr_t;
typedef unsigned long u_long;
typedef unsigned int u_int;
typedef unsigned short u_short;
typedef unsigned char u_char;
typedef unsigned int mode_t;
typedef u_int uid_t;
typedef u_int gid_t;
typedef int key_t;
#define IPC_PRIVATE ((key_t)0)
/* Common IPC operation flag definitions. We'll use
** the Unix values unless we find a reason not to.
*/
#define IPC_CREAT 0001000 /* create entry if key doesn't exist */
#define IPC_EXCL 0002000 /* fail if key exists */
#define IPC_NOWAIT 0004000 /* error if request must wait */
struct sembuf
{
u_short sem_num;
short sem_op;
short sem_flg;
};
#define USE_POSIX_TIME
#undef HAVE_RINT
#define MAXHOSTNAMELEN 12 /* where is the official definition of this? */
#define MAXPATHLEN _MAX_PATH /* in winsock.h */
/* NT has stricmp not strcasecmp. Which is ANSI? */
#define strcasecmp(a,b) _stricmp(a,b)
#define isascii(a) __isascii(a)
#define random() rand()
/* These are bogus values used so that we can compile ipc.c */
#define SETALL 2
#define SETVAL 3
#define IPC_RMID 4
#define GETNCNT 5
#define GETVAL 6
此差异已折叠。
Copyright 1992, 1993, 1994 Henry Spencer. All rights reserved.
This software is not subject to any license of the American Telephone
and Telegraph Company or of the Regents of the University of California.
Permission is granted to anyone to use this software for any purpose on
any computer system, and to alter it and redistribute it, subject
to the following restrictions:
1. The author is not responsible for the consequences of use of this
software, no matter how awful, even if they arise from flaws in it.
2. The origin of this software must not be misrepresented, either by
explicit claim or by omission. Since few users ever read sources,
credits must appear in the documentation.
3. Altered versions must be plainly marked as such, and must not be
misrepresented as being the original software. Since few users
ever read sources, credits must appear in the documentation.
4. This notice may not be removed or altered.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
/*-
* Copyright (c) 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)COPYRIGHT 8.1 (Berkeley) 3/16/94
*/
# @(#)WHATSNEW 8.3 (Berkeley) 3/18/94
New in alpha3.4: The complex bug alluded to below has been fixed (in a
slightly kludgey temporary way that may hurt efficiency a bit; this is
another "get it out the door for 4.4" release). The tests at the end of
the tests file have accordingly been uncommented. The primary sign of
the bug was that something like a?b matching ab matched b rather than ab.
(The bug was essentially specific to this exact situation, else it would
have shown up earlier.)
New in alpha3.3: The definition of word boundaries has been altered
slightly, to more closely match the usual programming notion that "_"
is an alphabetic. Stuff used for pre-ANSI systems is now in a subdir,
and the makefile no longer alludes to it in mysterious ways. The
makefile has generally been cleaned up some. Fixes have been made
(again!) so that the regression test will run without -DREDEBUG, at
the cost of weaker checking. A workaround for a bug in some folks'
<assert.h> has been added. And some more things have been added to
tests, including a couple right at the end which are commented out
because the code currently flunks them (complex bug; fix coming).
Plus the usual minor cleanup.
New in alpha3.2: Assorted bits of cleanup and portability improvement
(the development base is now a BSDI system using GCC instead of an ancient
Sun system, and the newer compiler exposed some glitches). Fix for a
serious bug that affected REs using many [] (including REG_ICASE REs
because of the way they are implemented), *sometimes*, depending on
memory-allocation patterns. The header-file prototypes no longer name
the parameters, avoiding possible name conflicts. The possibility that
some clot has defined CHAR_MIN as (say) `-128' instead of `(-128)' is
now handled gracefully. "uchar" is no longer used as an internal type
name (too many people have the same idea). Still the same old lousy
performance, alas.
New in alpha3.1: Basically nothing, this release is just a bookkeeping
convenience. Stay tuned.
New in alpha3.0: Performance is no better, alas, but some fixes have been
made and some functionality has been added. (This is basically the "get
it out the door in time for 4.4" release.) One bug fix: regfree() didn't
free the main internal structure (how embarrassing). It is now possible
to put NULs in either the RE or the target string, using (resp.) a new
REG_PEND flag and the old REG_STARTEND flag. The REG_NOSPEC flag to
regcomp() makes all characters ordinary, so you can match a literal
string easily (this will become more useful when performance improves!).
There are now primitives to match beginnings and ends of words, although
the syntax is disgusting and so is the implementation. The REG_ATOI
debugging interface has changed a bit. And there has been considerable
internal cleanup of various kinds.
New in alpha2.3: Split change list out of README, and moved flags notes
into Makefile. Macro-ized the name of regex(7) in regex(3), since it has
to change for 4.4BSD. Cleanup work in engine.c, and some new regression
tests to catch tricky cases thereof.
New in alpha2.2: Out-of-date manpages updated. Regerror() acquires two
small extensions -- REG_ITOA and REG_ATOI -- which avoid debugging kludges
in my own test program and might be useful to others for similar purposes.
The regression test will now compile (and run) without REDEBUG. The
BRE \$ bug is fixed. Most uses of "uchar" are gone; it's all chars now.
Char/uchar parameters are now written int/unsigned, to avoid possible
portability problems with unpromoted parameters. Some unsigned casts have
been introduced to minimize portability problems with shifting into sign
bits.
New in alpha2.1: Lots of little stuff, cleanup and fixes. The one big
thing is that regex.h is now generated, using mkh, rather than being
supplied in the distribution; due to circularities in dependencies,
you have to build regex.h explicitly by "make h". The two known bugs
have been fixed (and the regression test now checks for them), as has a
problem with assertions not being suppressed in the absence of REDEBUG.
No performance work yet.
New in alpha2: Backslash-anything is an ordinary character, not an
error (except, of course, for the handful of backslashed metacharacters
in BREs), which should reduce script breakage. The regression test
checks *where* null strings are supposed to match, and has generally
been tightened up somewhat. Small bug fixes in parameter passing (not
harmful, but technically errors) and some other areas. Debugging
invoked by defining REDEBUG rather than not defining NDEBUG.
New in alpha+3: full prototyping for internal routines, using a little
helper program, mkh, which extracts prototypes given in stylized comments.
More minor cleanup. Buglet fix: it's CHAR_BIT, not CHAR_BITS. Simple
pre-screening of input when a literal string is known to be part of the
RE; this does wonders for performance.
New in alpha+2: minor bits of cleanup. Notably, the number "32" for the
word width isn't hardwired into regexec.c any more, the public header
file prototypes the functions if __STDC__ is defined, and some small typos
in the manpages have been fixed.
New in alpha+1: improvements to the manual pages, and an important
extension, the REG_STARTEND option to regexec().
/*-
* Copyright (c) 1992, 1993, 1994 Henry Spencer.
* Copyright (c) 1992, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Henry Spencer.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)cclass.h 8.3 (Berkeley) 3/20/94
*/
/* 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, ""
};
/*-
* Copyright (c) 1992, 1993, 1994 Henry Spencer.
* Copyright (c) 1992, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Henry Spencer.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)cname.h 8.3 (Berkeley) 3/20/94
*/
/* 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,
};
此差异已折叠。
.\" Copyright (c) 1992, 1993, 1994 Henry Spencer.
.\" Copyright (c) 1992, 1993, 1994
.\" The Regents of the University of California. All rights reserved.
.\"
.\" This code is derived from software contributed to Berkeley by
.\" Henry Spencer.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by the University of
.\" California, Berkeley and its contributors.
.\" 4. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" @(#)re_format.7 8.3 (Berkeley) 3/20/94
.\"
.TH RE_FORMAT 7 "March 20, 1994"
.SH NAME
re_format \- POSIX 1003.2 regular expressions
.SH DESCRIPTION
Regular expressions (``RE''s),
as defined in POSIX 1003.2, come in two forms:
modern REs (roughly those of
.IR egrep ;
1003.2 calls these ``extended'' REs)
and obsolete REs (roughly those of
.IR ed ;
1003.2 ``basic'' REs).
Obsolete REs mostly exist for backward compatibility in some old programs;
they will be discussed at the end.
1003.2 leaves some aspects of RE syntax and semantics open;
`\(dg' marks decisions on these aspects that
may not be fully portable to other 1003.2 implementations.
.PP
A (modern) RE is one\(dg or more non-empty\(dg \fIbranches\fR,
separated by `|'.
It matches anything that matches one of the branches.
.PP
A branch is one\(dg or more \fIpieces\fR, concatenated.
It matches a match for the first, followed by a match for the second, etc.
.PP
A piece is an \fIatom\fR possibly followed
by a single\(dg `*', `+', `?', or \fIbound\fR.
An atom followed by `*' matches a sequence of 0 or more matches of the atom.
An atom followed by `+' matches a sequence of 1 or more matches of the atom.
An atom followed by `?' matches a sequence of 0 or 1 matches of the atom.
.PP
A \fIbound\fR is `{' followed by an unsigned decimal integer,
possibly followed by `,'
possibly followed by another unsigned decimal integer,
always followed by `}'.
The integers must lie between 0 and RE_DUP_MAX (255\(dg) inclusive,
and if there are two of them, the first may not exceed the second.
An atom followed by a bound containing one integer \fIi\fR
and no comma matches
a sequence of exactly \fIi\fR matches of the atom.
An atom followed by a bound
containing one integer \fIi\fR and a comma matches
a sequence of \fIi\fR or more matches of the atom.
An atom followed by a bound
containing two integers \fIi\fR and \fIj\fR matches
a sequence of \fIi\fR through \fIj\fR (inclusive) matches of the atom.
.PP
An atom is a regular expression enclosed in `()' (matching a match for the
regular expression),
an empty set of `()' (matching the null string)\(dg,
a \fIbracket expression\fR (see below), `.'
(matching any single character), `^' (matching the null string at the
beginning of a line), `$' (matching the null string at the
end of a line), a `\e' followed by one of the characters
`^.[$()|*+?{\e'
(matching that character taken as an ordinary character),
a `\e' followed by any other character\(dg
(matching that character taken as an ordinary character,
as if the `\e' had not been present\(dg),
or a single character with no other significance (matching that character).
A `{' followed by a character other than a digit is an ordinary
character, not the beginning of a bound\(dg.
It is illegal to end an RE with `\e'.
.PP
A \fIbracket expression\fR is a list of characters enclosed in `[]'.
It normally matches any single character from the list (but see below).
If the list begins with `^',
it matches any single character
(but see below) \fInot\fR from the rest of the list.
If two characters in the list are separated by `\-', this is shorthand
for the full \fIrange\fR of characters between those two (inclusive) in the
collating sequence,
e.g. `[0-9]' in ASCII matches any decimal digit.
It is illegal\(dg for two ranges to share an
endpoint, e.g. `a-c-e'.
Ranges are very collating-sequence-dependent,
and portable programs should avoid relying on them.
.PP
To include a literal `]' in the list, make it the first character
(following a possible `^').
To include a literal `\-', make it the first or last character,
or the second endpoint of a range.
To use a literal `\-' as the first endpoint of a range,
enclose it in `[.' and `.]' to make it a collating element (see below).
With the exception of these and some combinations using `[' (see next
paragraphs), all other special characters, including `\e', lose their
special significance within a bracket expression.
.PP
Within a bracket expression, a collating element (a character,
a multi-character sequence that collates as if it were a single character,
or a collating-sequence name for either)
enclosed in `[.' and `.]' stands for the
sequence of characters of that collating element.
The sequence is a single element of the bracket expression's list.
A bracket expression containing a multi-character collating element
can thus match more than one character,
e.g. if the collating sequence includes a `ch' collating element,
then the RE `[[.ch.]]*c' matches the first five characters
of `chchcc'.
.PP
Within a bracket expression, a collating element enclosed in `[=' and
`=]' is an equivalence class, standing for the sequences of characters
of all collating elements equivalent to that one, including itself.
(If there are no other equivalent collating elements,
the treatment is as if the enclosing delimiters were `[.' and `.]'.)
For example, if o and \o'o^' are the members of an equivalence class,
then `[[=o=]]', `[[=\o'o^'=]]', and `[o\o'o^']' are all synonymous.
An equivalence class may not\(dg be an endpoint
of a range.
.PP
Within a bracket expression, the name of a \fIcharacter class\fR enclosed
in `[:' and `:]' stands for the list of all characters belonging to that
class.
Standard character class names are:
.PP
.RS
.nf
.ta 3c 6c 9c
alnum digit punct
alpha graph space
blank lower upper
cntrl print xdigit
.fi
.RE
.PP
These stand for the character classes defined in
.IR ctype (3).
A locale may provide others.
A character class may not be used as an endpoint of a range.
.PP
There are two special cases\(dg of bracket expressions:
the bracket expressions `[[:<:]]' and `[[:>:]]' match the null string at
the beginning and end of a word respectively.
A word is defined as a sequence of
word characters
which is neither preceded nor followed by
word characters.
A word character is an
.I alnum
character (as defined by
.IR ctype (3))
or an underscore.
This is an extension,
compatible with but not specified by POSIX 1003.2,
and should be used with
caution in software intended to be portable to other systems.
.PP
In the event that an RE could match more than one substring of a given
string,
the RE matches the one starting earliest in the string.
If the RE could match more than one substring starting at that point,
it matches the longest.
Subexpressions also match the longest possible substrings, subject to
the constraint that the whole match be as long as possible,
with subexpressions starting earlier in the RE taking priority over
ones starting later.
Note that higher-level subexpressions thus take priority over
their lower-level component subexpressions.
.PP
Match lengths are measured in characters, not collating elements.
A null string is considered longer than no match at all.
For example,
`bb*' matches the three middle characters of `abbbc',
`(wee|week)(knights|nights)' matches all ten characters of `weeknights',
when `(.*).*' is matched against `abc' the parenthesized subexpression
matches all three characters, and
when `(a*)*' is matched against `bc' both the whole RE and the parenthesized
subexpression match the null string.
.PP
If case-independent matching is specified,
the effect is much as if all case distinctions had vanished from the
alphabet.
When an alphabetic that exists in multiple cases appears as an
ordinary character outside a bracket expression, it is effectively
transformed into a bracket expression containing both cases,
e.g. `x' becomes `[xX]'.
When it appears inside a bracket expression, all case counterparts
of it are added to the bracket expression, so that (e.g.) `[x]'
becomes `[xX]' and `[^x]' becomes `[^xX]'.
.PP
No particular limit is imposed on the length of REs\(dg.
Programs intended to be portable should not employ REs longer
than 256 bytes,
as an implementation can refuse to accept such REs and remain
POSIX-compliant.
.PP
Obsolete (``basic'') regular expressions differ in several respects.
`|', `+', and `?' are ordinary characters and there is no equivalent
for their functionality.
The delimiters for bounds are `\e{' and `\e}',
with `{' and `}' by themselves ordinary characters.
The parentheses for nested subexpressions are `\e(' and `\e)',
with `(' and `)' by themselves ordinary characters.
`^' is an ordinary character except at the beginning of the
RE or\(dg the beginning of a parenthesized subexpression,
`$' is an ordinary character except at the end of the
RE or\(dg the end of a parenthesized subexpression,
and `*' is an ordinary character if it appears at the beginning of the
RE or the beginning of a parenthesized subexpression
(after a possible leading `^').
Finally, there is one new type of atom, a \fIback reference\fR:
`\e' followed by a non-zero decimal digit \fId\fR
matches the same sequence of characters
matched by the \fId\fRth parenthesized subexpression
(numbering subexpressions by the positions of their opening parentheses,
left to right),
so that (e.g.) `\e([bc]\e)\e1' matches `bb' or `cc' but not `bc'.
.SH SEE ALSO
regex(3)
.PP
POSIX 1003.2, section 2.8 (Regular Expression Notation).
.SH BUGS
Having two kinds of REs is a botch.
.PP
The current 1003.2 spec says that `)' is an ordinary character in
the absence of an unmatched `(';
this was an unintentional result of a wording error,
and change is likely.
Avoid relying on it.
.PP
Back references are a dreadful botch,
posing major problems for efficient implementations.
They are also somewhat vaguely defined
(does
`a\e(\e(b\e)*\e2\e)*d' match `abbbd'?).
Avoid using them.
.PP
1003.2's specification of case-independent matching is vague.
The ``one case implies all cases'' definition given above
is current consensus among implementors as to the right interpretation.
.PP
The syntax for word boundaries is incredibly ugly.
此差异已折叠。
/*-
* Copyright (c) 1992, 1993, 1994 Henry Spencer.
* Copyright (c) 1992, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Henry Spencer.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)regerror.c 8.4 (Berkeley) 3/20/94
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)regerror.c 8.4 (Berkeley) 3/20/94";
#endif /* LIBC_SCCS and not lint */
#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"
/* ========= begin header generated by ./mkh ========= */
#ifdef __cplusplus
extern "C" {
#endif
/* === regerror.c === */
static char *regatoi __P((const regex_t *preg, char *localbuf));
#ifdef __cplusplus
}
#endif
/* ========= end header generated by ./mkh ========= */
/*
= #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&REG_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);
}
此差异已折叠。
/*-
* Copyright (c) 1992 Henry Spencer.
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Henry Spencer of the University of Toronto.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)regex.h 8.2 (Berkeley) 1/3/94
*/
#ifndef _REGEX_H_
#define _REGEX_H_
#include <sys/cdefs.h>
/* types */
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;
/* regcomp() flags */
#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
/* regerror() flags */
#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 (!) */
/* regexec() flags */
#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 */
__BEGIN_DECLS
int regcomp __P((regex_t *, const char *, int));
size_t regerror __P((int, const regex_t *, char *, size_t));
int regexec __P((const regex_t *,
const char *, size_t, regmatch_t [], int));
void regfree __P((regex_t *));
__END_DECLS
#endif /* !_REGEX_H_ */
此差异已折叠。
此差异已折叠。
/*
* Copyright (c) 1986 by University of Toronto.
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley
* by Henry Spencer.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)regexp.h 8.1 (Berkeley) 6/2/93
*/
#ifndef _REGEXP_H_
#define _REGEXP_H_
/*
* Definitions etc. for regexp(3) routines.
*
* Caveat: this is V8 regexp(3) [actually, a reimplementation thereof],
* not the System V one.
*/
#define NSUBEXP 10
typedef struct regexp {
char *startp[NSUBEXP];
char *endp[NSUBEXP];
char regstart; /* Internal use only. */
char reganch; /* Internal use only. */
char *regmust; /* Internal use only. */
int regmlen; /* Internal use only. */
char program[1]; /* Unwarranted chumminess with compiler. */
} regexp;
#include <sys/cdefs.h>
__BEGIN_DECLS
regexp *regcomp __P((const char *));
int regexec __P((const regexp *, const char *));
void regsub __P((const regexp *, const char *, char *));
void regerror __P((const char *));
__END_DECLS
#endif /* !_REGEXP_H_ */
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册