Initial import of the CDE 2.1.30 sources from the Open Group.
This commit is contained in:
53
cde/lib/DtSvc/DtCodelibs/Imakefile
Normal file
53
cde/lib/DtSvc/DtCodelibs/Imakefile
Normal file
@@ -0,0 +1,53 @@
|
||||
XCOMM $XConsortium: Imakefile /main/6 1996/08/20 14:48:43 drk $
|
||||
XCOMM (c) Copyright 1996 Digital Equipment Corporation.
|
||||
XCOMM (c) Copyright 1993-1994,1996 Hewlett-Packard Company.
|
||||
XCOMM (c) Copyright 1993-1994,1996 International Business Machines Corp.
|
||||
XCOMM (c) Copyright 1993-1994,1996 Sun Microsystems, Inc.
|
||||
XCOMM (c) Copyright 1993-1994,1996 Novell, Inc.
|
||||
XCOMM (c) Copyright 1996 FUJITSU LIMITED.
|
||||
XCOMM (c) Copyright 1996 Hitachi.
|
||||
|
||||
#define DoNormalLib NormalLibDtSvc
|
||||
#define DoSharedLib SharedLibDtSvc
|
||||
#define DoDebugLib DebugLibDtSvc
|
||||
#define DoProfileLib ProfileLibDtSvc
|
||||
#define LibName DtSvc
|
||||
#define SoRev SODTSVCREV
|
||||
#define LibHeaders NO
|
||||
#define LibCreate NO
|
||||
|
||||
#define CplusplusSource YES
|
||||
DEPEND_DEFINES = $(CXXDEPENDINCLUDES)
|
||||
|
||||
#include <Threads.tmpl>
|
||||
|
||||
#ifndef DtSvcDefines
|
||||
# define DtSvcDefines -DXK_MISCELLANY -DMULTIBYTE
|
||||
#endif
|
||||
DEFINES = DtSvcDefines
|
||||
INCLUDES = -I. -I../include
|
||||
|
||||
#if defined(RsArchitecture)
|
||||
CXXEXTRA_DEFINES = -qlanglvl=compat
|
||||
#endif
|
||||
|
||||
|
||||
SRCS = buf.C filegen.C mbschr.C \
|
||||
pathcollapse.C shellscan.C strend.C \
|
||||
strhash.C stringio.C strtokx.C \
|
||||
strwcmp.C privbuf.C strcase.C
|
||||
|
||||
/* WARNING!!!!
|
||||
* Any .o's added to this list need to be added to DTCODELIBS_OBJS3
|
||||
* and SHARED_DTCODELIBS_OBJS3 in the DtSvc Imakefile.
|
||||
*/
|
||||
OBJS = buf.o filegen.o mbschr.o \
|
||||
pathcollapse.o shellscan.o strend.o \
|
||||
strhash.o stringio.o strtokx.o \
|
||||
strwcmp.o privbuf.o strcase.o
|
||||
|
||||
#include <Library.tmpl>
|
||||
|
||||
SubdirLibraryRule($(OBJS))
|
||||
|
||||
DependTarget()
|
||||
105
cde/lib/DtSvc/DtCodelibs/buf.C
Normal file
105
cde/lib/DtSvc/DtCodelibs/buf.C
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* File: buf.C $TOG: buf.C /main/5 1998/01/21 18:01:14 mgreess $
|
||||
*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993, 1994 Novell, Inc.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <codelibs/nl_hack.h>
|
||||
#include "buf.h"
|
||||
|
||||
void
|
||||
_SHXbuf::start_token()
|
||||
{
|
||||
vec[vec.size()] = (char *)buf.size();
|
||||
is_pattern = FALSE;
|
||||
_new_token = FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
_SHXbuf::quote(Quote q)
|
||||
{
|
||||
_quote ^= q;
|
||||
if (_new_token)
|
||||
start_token();
|
||||
}
|
||||
|
||||
void
|
||||
_SHXbuf::append(int const ch, char flag)
|
||||
{
|
||||
flag |= _quote;
|
||||
|
||||
if (ch == '\0' && !_new_token)
|
||||
_new_token = TRUE;
|
||||
else if (_new_token)
|
||||
start_token();
|
||||
|
||||
if (flag == NOQUOTE)
|
||||
if (ch == '*' || ch == '?' || ch == '[')
|
||||
if (glob)
|
||||
is_pattern = TRUE;
|
||||
else
|
||||
flag |= SINGLEQUOTE;
|
||||
|
||||
if (ch <= 0xFF)
|
||||
{
|
||||
// 8-bit char
|
||||
flags[buf.size()] = flag;
|
||||
buf[buf.size()] = (unsigned char)ch;
|
||||
}
|
||||
else
|
||||
{
|
||||
// multibyte char
|
||||
long sz = buf.size();
|
||||
|
||||
for (int i=0; i<MB_CUR_MAX; i++) flags[sz+i] = flag;
|
||||
buf.reset(sz + MB_CUR_MAX);
|
||||
char *cp = &buf.elt(sz);
|
||||
WCHAR(ch, cp);
|
||||
}
|
||||
|
||||
// expand token into filename(s) if appropriate
|
||||
if (ch == '\0' && (is_pattern || completion))
|
||||
if (!(flag & EXPANDQUOTE))
|
||||
filegen();
|
||||
}
|
||||
|
||||
void
|
||||
_SHXbuf::append(char const *cp, char flag)
|
||||
{
|
||||
wchar_t __nlh_char[1];
|
||||
|
||||
do
|
||||
append((int)CHARAT(cp), flag);
|
||||
while (CHARADV(cp) != '\0');
|
||||
}
|
||||
|
||||
void
|
||||
_SHXbuf::reset(boolean g, boolean comp)
|
||||
{
|
||||
glob = (boolean) !!g;
|
||||
completion = (boolean ) !!comp;
|
||||
is_pattern = FALSE;
|
||||
_new_token = TRUE;
|
||||
_quote = NOQUOTE;
|
||||
buf.reset(0);
|
||||
flags.reset(0);
|
||||
vec.reset(0);
|
||||
}
|
||||
|
||||
// Convert the subscripts that are stored in vec[] into
|
||||
// char pointers. The only legal operation on _SHXbuf after
|
||||
// calling vector is to call reset.
|
||||
char **
|
||||
_SHXbuf::vector()
|
||||
{
|
||||
for (int i = 0; i < vec.size(); i++)
|
||||
vec[i] = &buf[long(vec[i])];
|
||||
|
||||
vec[i] = NULL;
|
||||
|
||||
return vec.getarr();
|
||||
}
|
||||
49
cde/lib/DtSvc/DtCodelibs/buf.h
Normal file
49
cde/lib/DtSvc/DtCodelibs/buf.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* File: buf.h $XConsortium: buf.h /main/3 1995/10/26 16:07:20 rswiston $
|
||||
*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993, 1994 Novell, Inc.
|
||||
*/
|
||||
#include <codelibs/boolean.h>
|
||||
#define __PRIVATE_
|
||||
#include <codelibs/privbuf.h>
|
||||
|
||||
#define NOQUOTE 0
|
||||
#define SINGLEQUOTE 1
|
||||
#define DOUBLEQUOTE 2
|
||||
#define EXPANDQUOTE 4
|
||||
|
||||
typedef unsigned char Quote;
|
||||
|
||||
class _SHXcomponents;
|
||||
|
||||
class _SHXbuf
|
||||
{
|
||||
boolean glob;
|
||||
boolean completion;
|
||||
boolean is_pattern;
|
||||
Quote _quote;
|
||||
boolean _new_token;
|
||||
privbuf_charbuf buf;
|
||||
privbuf_charbuf flags;
|
||||
privbuf_strvec vec;
|
||||
void start_token();
|
||||
void filegen();
|
||||
void expand(_SHXcomponents&, char* const, char*, int);
|
||||
public:
|
||||
_SHXbuf() {reset(TRUE, FALSE);}
|
||||
void reset(boolean glob, boolean completion);
|
||||
void append(int const ch, char flag = 0);
|
||||
void append(char const *cp, char flag = 0);
|
||||
int ntokens() {return vec.size();}
|
||||
boolean new_token() {return _new_token;}
|
||||
Quote quote() {return _quote;}
|
||||
void quote(Quote);
|
||||
char **vector();
|
||||
};
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
281
cde/lib/DtSvc/DtCodelibs/filegen.C
Normal file
281
cde/lib/DtSvc/DtCodelibs/filegen.C
Normal file
@@ -0,0 +1,281 @@
|
||||
/*
|
||||
* File: filegen.C $TOG: filegen.C /main/7 1999/10/14 15:05:25 mgreess $
|
||||
*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993, 1994 Novell, Inc.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#define X_INCLUDE_DIRENT_H
|
||||
#define XOS_USE_XT_LOCKING
|
||||
#include <X11/Xos_r.h>
|
||||
#include <codelibs/stringx.h>
|
||||
#include <codelibs/nl_hack.h>
|
||||
#include "buf.h"
|
||||
#include "DtSvcLock.h"
|
||||
|
||||
#ifndef MAXPATHLEN
|
||||
# define MAXPATHLEN 1024
|
||||
#endif
|
||||
|
||||
#ifdef XTHREADS
|
||||
extern "C" {
|
||||
extern void XtProcessLock(void);
|
||||
extern void XtProcessUnlock(void);
|
||||
}
|
||||
#endif
|
||||
|
||||
struct _SHXcomponent
|
||||
{
|
||||
boolean is_pattern;
|
||||
long offset; // subscript in path buffer
|
||||
char *ptr; // pointer into path buffer
|
||||
};
|
||||
|
||||
declare_array(_SHXcomponents, _SHXcomponent, 4)
|
||||
|
||||
// recursive routine to expand the wildcard path represented in stack into
|
||||
// all possible expansions. The expansions are appended to _SHXbuf::vec.
|
||||
// filebuf is a scratch buffer passed in by the caller and is used to build
|
||||
// intermediate paths. end is a pointer to the position in filebuf where
|
||||
// the calling routine left off.
|
||||
void
|
||||
_SHXbuf::expand(_SHXcomponents &stack,
|
||||
char *const filebuf, char *end, int compnum)
|
||||
{
|
||||
*end = '\0';
|
||||
|
||||
if (compnum == stack.size())
|
||||
return;
|
||||
|
||||
_SHXcomponent &comp = stack[compnum];
|
||||
|
||||
// double-slash?
|
||||
if (comp.ptr[0] == '\0')
|
||||
{
|
||||
if (compnum + 1 == stack.size())
|
||||
append(filebuf, EXPANDQUOTE);
|
||||
else
|
||||
{
|
||||
*end++ = '/';
|
||||
expand(stack, filebuf, end, compnum + 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// performance optimization: if this path component
|
||||
// doesn't contain a wildcard, avoid doing an opendir()
|
||||
if (!comp.is_pattern)
|
||||
{
|
||||
strcpy(end, comp.ptr);
|
||||
if (compnum + 1 == stack.size())
|
||||
{
|
||||
// last component, just see if the path really points to something
|
||||
if (access(filebuf, F_OK) != -1)
|
||||
append(filebuf, EXPANDQUOTE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// intermediate directory just append this component and keep going
|
||||
char *end2 = strend(end);
|
||||
*end2++ = '/';
|
||||
expand(stack, filebuf, end2, compnum + 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// We have a wildcard component, open and scan its parent directory
|
||||
// and look for matches.
|
||||
DIR *dir = opendir(filebuf[0] == '\0' ? "." : filebuf);
|
||||
if (dir == NULL)
|
||||
return;
|
||||
|
||||
_Xreaddirparams dir_buf;
|
||||
struct dirent *ent;
|
||||
|
||||
memset((char*) &dir_buf, 0, sizeof(_Xreaddirparams));
|
||||
while ((ent = _XReaddir(dir, dir_buf)) != NULL)
|
||||
{
|
||||
// deleted file?
|
||||
if (ent->d_ino == 0 || ent->d_name[0] == '\0')
|
||||
continue;
|
||||
|
||||
// right name?
|
||||
if (comp.is_pattern)
|
||||
{
|
||||
wchar_t __nlh_char[1];
|
||||
|
||||
// Must have explicit match for leading '.'
|
||||
if (CHARAT(ent->d_name) == '.' && CHARAT(comp.ptr) != '.')
|
||||
continue;
|
||||
|
||||
if (strwcmp(comp.ptr, ent->d_name) != 0)
|
||||
continue;
|
||||
}
|
||||
else if (strcmp(comp.ptr, ent->d_name) != 0)
|
||||
continue;
|
||||
|
||||
strcpy(end, ent->d_name);
|
||||
if (compnum + 1 == stack.size())
|
||||
append(filebuf, EXPANDQUOTE);
|
||||
else
|
||||
{
|
||||
char *end2 = end + strlen (ent->d_name);
|
||||
*end2++ = '/';
|
||||
expand(stack, filebuf, end2, compnum + 1);
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
}
|
||||
|
||||
|
||||
//extern "C" { void qsort(void *, unsigned, int, ...); };
|
||||
|
||||
static char *bufptr;
|
||||
|
||||
static int
|
||||
//compar(int &v1, int &v2)
|
||||
compar(const void *v1, const void *v2)
|
||||
{
|
||||
int result;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
result = strcmp(&bufptr[*(int*)v1], &bufptr[*(int*)v2]);
|
||||
_DtSvcProcessUnlock();
|
||||
return (result);
|
||||
}
|
||||
|
||||
void
|
||||
_SHXbuf::filegen()
|
||||
{
|
||||
privbuf_charbuf path;
|
||||
_SHXcomponents stack;
|
||||
|
||||
long vecstart = vec.size() - 1;
|
||||
if (vecstart < 0)
|
||||
return;
|
||||
|
||||
long bufstart = long(vec[vecstart]);
|
||||
|
||||
// Parse the file path, breaking it up into individual components.
|
||||
// Each component is marked as being either a wildcard component
|
||||
// or not. The wildcard components will have a '\' placed before
|
||||
// any quoted wildcard characters. The non-wildcard components
|
||||
// will be left unchanged.
|
||||
int bufpos = (int) bufstart;
|
||||
while (bufpos < buf.size())
|
||||
{
|
||||
_SHXcomponent & comp = stack[stack.size()];
|
||||
comp.is_pattern = FALSE;
|
||||
comp.offset = path.size();
|
||||
comp.ptr = NULL;
|
||||
int startpos = bufpos;
|
||||
|
||||
int ch;
|
||||
do
|
||||
{
|
||||
ch = buf[bufpos];
|
||||
switch (ch)
|
||||
{
|
||||
case '/':
|
||||
ch = '\0';
|
||||
break;
|
||||
case '*':
|
||||
case '?':
|
||||
case '[':
|
||||
if (flags[bufpos] == NOQUOTE)
|
||||
comp.is_pattern = TRUE;
|
||||
else
|
||||
path[path.size()] = '\\';
|
||||
break;
|
||||
}
|
||||
|
||||
path[path.size()] = ch;
|
||||
bufpos++;
|
||||
} while (ch != '\0');
|
||||
|
||||
// Add a '*' to the end of the last component if needed
|
||||
// for completion.
|
||||
if (bufpos >= buf.size()) // last component?
|
||||
if (bufpos > bufstart + 1) // non-null string?
|
||||
if (completion && !is_pattern)
|
||||
{
|
||||
path[path.size() - 1] = '*';
|
||||
path[path.size()] = '\0';
|
||||
comp.is_pattern = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
// If it wasn't a pattern, remove all of the '\' characters
|
||||
// that were added.
|
||||
if (!comp.is_pattern)
|
||||
{
|
||||
int len = bufpos - startpos - 1;
|
||||
strncpy(&path[comp.offset], &buf[startpos], len);
|
||||
path[comp.offset + len] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
// Fill in the character pointer values for all of the components.
|
||||
// We couldn't do this in the first pass because path is a
|
||||
// dynamic array.
|
||||
char *pathbuf = path.getarr();
|
||||
for (int i = 0; i < stack.size(); i++)
|
||||
stack[i].ptr = &pathbuf[stack[i].offset];
|
||||
|
||||
// Remove the token that we just copied from the return vector
|
||||
// so that we can replace it with its expansion.
|
||||
vec.reset(vecstart);
|
||||
|
||||
char filebuf[MAXPATHLEN];
|
||||
expand(stack, filebuf, filebuf, 0);
|
||||
|
||||
if (vec.size() == vecstart) // no matches?
|
||||
{
|
||||
vec[vecstart] = (char *)bufstart; // restore orig. token
|
||||
return;
|
||||
}
|
||||
|
||||
// alphabetize the expansion to make it look pretty like ksh does.
|
||||
_DtSvcProcessLock();
|
||||
bufptr = buf.getarr();
|
||||
qsort(&vec[vecstart], (unsigned int)(vec.size() - vecstart),
|
||||
sizeof (char *), compar);
|
||||
|
||||
// Find the longest match if we are doing completion:
|
||||
if (completion)
|
||||
{
|
||||
// compare all entries to a copy of the first entry
|
||||
strcpy(filebuf, &bufptr[long(vec[0])]);
|
||||
|
||||
for (long i = 1; i < vec.size(); i++)
|
||||
{
|
||||
register char *ref = filebuf;
|
||||
register char *ptr = &bufptr[long(vec[i])];
|
||||
while (*ref == *ptr && *ref != '\0' && *ptr != '\0')
|
||||
ref++, ptr++;
|
||||
|
||||
*ref = '\0'; // shorten the reference copy
|
||||
}
|
||||
|
||||
// Now store the best match as the first token. We will
|
||||
// have to shift the expansion vector down by one to
|
||||
// make room.
|
||||
for (i = vec.size(); i > 0; --i)
|
||||
{
|
||||
register char *val = vec[i - 1];
|
||||
vec[i] = val;
|
||||
}
|
||||
vec[0] = (char *)buf.size();
|
||||
append(filebuf, EXPANDQUOTE);
|
||||
vec.reset(vec.size() - 1); // adjust for the append
|
||||
}
|
||||
_DtSvcProcessUnlock();
|
||||
}
|
||||
|
||||
implement_array(_SHXcomponents, _SHXcomponent, 4)
|
||||
36
cde/lib/DtSvc/DtCodelibs/mbschr.C
Normal file
36
cde/lib/DtSvc/DtCodelibs/mbschr.C
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* $XConsortium: mbschr.C /main/5 1996/06/21 17:36:36 ageorge $
|
||||
*
|
||||
* (c) Copyright 1996 Digital Equipment Corporation.
|
||||
* (c) Copyright 1993,1994,1996 Hewlett-Packard Company.
|
||||
* (c) Copyright 1993,1994,1996 International Business Machines Corp.
|
||||
* (c) Copyright 1993,1994,1996 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993,1994,1996 Novell, Inc.
|
||||
* (c) Copyright 1996 FUJITSU LIMITED.
|
||||
* (c) Copyright 1996 Hitachi.
|
||||
*/
|
||||
|
||||
#include <codelibs/mbstring.h>
|
||||
#include <codelibs/nl_hack.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
#if defined(__cplusplus) || defined(__STDC__)
|
||||
char *
|
||||
_mb_schr(const char *str, wchar_t ch)
|
||||
#else
|
||||
char *
|
||||
_mb_schr(str, ch)
|
||||
register unsigned char *str;
|
||||
register wchar_t ch;
|
||||
#endif
|
||||
{
|
||||
wchar_t __nlh_char[1];
|
||||
|
||||
for (; *str != '\0'; ADVANCE(str))
|
||||
if (CHARAT(str) == ch)
|
||||
return (char *)str;
|
||||
|
||||
return (char *)0;
|
||||
}
|
||||
162
cde/lib/DtSvc/DtCodelibs/pathcollapse.C
Normal file
162
cde/lib/DtSvc/DtCodelibs/pathcollapse.C
Normal file
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* $XConsortium: pathcollapse.C /main/5 1996/06/21 17:36:32 ageorge $
|
||||
*
|
||||
* (c) Copyright 1996 Digital Equipment Corporation.
|
||||
* (c) Copyright 1993,1994,1996 Hewlett-Packard Company.
|
||||
* (c) Copyright 1993,1994,1996 International Business Machines Corp.
|
||||
* (c) Copyright 1993,1994,1996 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993,1994,1996 Novell, Inc.
|
||||
* (c) Copyright 1996 FUJITSU LIMITED.
|
||||
* (c) Copyright 1996 Hitachi.
|
||||
*/
|
||||
#ifdef DOMAIN_ALLOW_MALLOC_OVERRIDE
|
||||
#include "/usr/include/apollo/shlib.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/param.h>
|
||||
#include <codelibs/nl_hack.h>
|
||||
#include <codelibs/pathutils.h>
|
||||
|
||||
#define SEP(P) (CHARAT(P) == '\0' || CHARAT(P) == '/')
|
||||
#define DOT(P) (CHARAT(P) == '.' && SEP((P) + 1))
|
||||
#define DOTDOT(P) (CHARAT(P) == '.' && DOT((P) + 1))
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char *
|
||||
pathcollapse(const char *src, char *dst, boolean show_dir)
|
||||
{
|
||||
int ch;
|
||||
const char *srcp;
|
||||
char *dstp, *sep;
|
||||
char *components[MAXPATHLEN / 2 + 1];
|
||||
char **comp = components;
|
||||
int length = src == NULL ? 0 : strlen(src);
|
||||
int dir_comp; /* TRUE if last component was . or .. */
|
||||
#ifdef apollo
|
||||
int double_slash = 0;
|
||||
#endif
|
||||
wchar_t __nlh_char[1];
|
||||
|
||||
if (length == 0 || length > MAXPATHLEN)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (dst == NULL)
|
||||
if ((dst = (char *)malloc(length + 1)) == NULL)
|
||||
return NULL;
|
||||
|
||||
#ifdef apollo
|
||||
/*
|
||||
* On apollo, a leading double-slash must be preserved, so we
|
||||
* copy the first slash and hide it from the rest of the code.
|
||||
*/
|
||||
if (CHARAT(src) == '/' && CHARAT(src + 1) == '/')
|
||||
{
|
||||
*dst++ = '/';
|
||||
src++;
|
||||
double_slash = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
srcp = src;
|
||||
dstp = dst;
|
||||
|
||||
do /* for each component of src */
|
||||
{
|
||||
*comp = dstp;
|
||||
|
||||
/* copy the component and trailing separator to dst */
|
||||
do
|
||||
{
|
||||
ch = (int)CHARAT(srcp);
|
||||
sep = dstp;
|
||||
WCHARADV(ch, dstp);
|
||||
if (ch == '\0')
|
||||
break;
|
||||
ADVANCE(srcp);
|
||||
} while (ch != '/');
|
||||
|
||||
dir_comp = ch == '/'; /* true if trailing '/' */
|
||||
|
||||
/* skip all adjacent '/' characters [the first is preserved] */
|
||||
while (CHARAT(srcp) == '/')
|
||||
ADVANCE(srcp);
|
||||
|
||||
/* remove redundant trailing slash */
|
||||
if (CHARAT(srcp) == '\0')
|
||||
if (sep > dst)
|
||||
*sep = ch = '\0';
|
||||
|
||||
if (DOT(*comp))
|
||||
{
|
||||
dir_comp = 1;
|
||||
dstp = *comp;
|
||||
if (dstp > dst)
|
||||
{
|
||||
sep = dstp - 1;
|
||||
*dstp = '\0';
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else if (DOTDOT(*comp))
|
||||
{
|
||||
dir_comp = 1;
|
||||
if (*comp > dst)
|
||||
{
|
||||
comp--;
|
||||
if (!DOTDOT(*comp))
|
||||
{
|
||||
dstp = *comp;
|
||||
if (dstp > dst)
|
||||
{
|
||||
sep = dstp - 1;
|
||||
*dstp = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
if (CHARAT(dst) == '/')
|
||||
{
|
||||
/* /.. is same as / */
|
||||
dstp = dst + 1;
|
||||
*dstp = '\0';
|
||||
comp++;
|
||||
}
|
||||
else
|
||||
dst[0] = '.';
|
||||
sep = dst + 1;
|
||||
*sep = '\0';
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
comp++;
|
||||
} while (ch != '\0');
|
||||
|
||||
if (show_dir)
|
||||
{
|
||||
if (dir_comp && (sep > dst + 1 || dst[0] != '/'))
|
||||
{
|
||||
*sep++ = '/';
|
||||
*sep = '\0';
|
||||
}
|
||||
}
|
||||
else if (sep > dst)
|
||||
*sep = '\0'; /* remove trailing '/' */
|
||||
|
||||
#ifdef apollo
|
||||
if (double_slash)
|
||||
dst--;
|
||||
#endif
|
||||
|
||||
return dst;
|
||||
}
|
||||
43
cde/lib/DtSvc/DtCodelibs/privbuf.C
Normal file
43
cde/lib/DtSvc/DtCodelibs/privbuf.C
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* $XConsortium: privbuf.C /main/4 1996/04/21 19:09:31 drk $
|
||||
*
|
||||
* (c) Copyright 1996 Digital Equipment Corporation.
|
||||
* (c) Copyright 1993,1994,1996 Hewlett-Packard Company.
|
||||
* (c) Copyright 1993,1994,1996 International Business Machines Corp.
|
||||
* (c) Copyright 1993,1994,1996 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993,1994,1996 Novell, Inc.
|
||||
* (c) Copyright 1996 FUJITSU LIMITED.
|
||||
* (c) Copyright 1996 Hitachi.
|
||||
*/
|
||||
#define __PRIVATE_
|
||||
#include <codelibs/privbuf.h>
|
||||
|
||||
implement_array(privbuf_charbuf, char, 128)
|
||||
implement_array(privbuf_strvec, char*, 128)
|
||||
|
||||
void privbuf_release(void **var)
|
||||
{
|
||||
if (var == NULL || *var == NULL)
|
||||
return;
|
||||
char *buf = (char*)*var;
|
||||
privbuf_func *p = (privbuf_func*)(void*)buf;
|
||||
*var = NULL;
|
||||
(*p)((void*)buf);
|
||||
}
|
||||
|
||||
void privbuf_freeprivbuf(void *buf)
|
||||
{
|
||||
privbuf_buffer *b = (privbuf_buffer*)buf;
|
||||
//delete b->buf;
|
||||
//delete b->vec;
|
||||
delete b;
|
||||
}
|
||||
|
||||
privbuf_buffer *privbuf_allocprivbuf()
|
||||
{
|
||||
privbuf_buffer *b = new privbuf_buffer;
|
||||
b->func = privbuf_freeprivbuf;
|
||||
//b->buf = new privbuf_charbuf;
|
||||
//b->vec = new privbuf_strvec;
|
||||
return b;
|
||||
}
|
||||
480
cde/lib/DtSvc/DtCodelibs/shellscan.C
Normal file
480
cde/lib/DtSvc/DtCodelibs/shellscan.C
Normal file
@@ -0,0 +1,480 @@
|
||||
/*
|
||||
* $TOG: shellscan.C /main/9 1999/10/14 15:05:42 mgreess $
|
||||
*
|
||||
* (c) Copyright 1996 Digital Equipment Corporation.
|
||||
* (c) Copyright 1993,1994,1996 Hewlett-Packard Company.
|
||||
* (c) Copyright 1993,1994,1996 International Business Machines Corp.
|
||||
* (c) Copyright 1993,1994,1996 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993,1994,1996 Novell, Inc.
|
||||
* (c) Copyright 1996 FUJITSU LIMITED.
|
||||
* (c) Copyright 1996 Hitachi.
|
||||
*/
|
||||
# if defined(apollo) && !defined(___GID_T)
|
||||
// This kludge is needed for the include conflicts mentioned below
|
||||
// Remove when no longer necessary
|
||||
# define _NEED___PID_T
|
||||
# endif
|
||||
|
||||
#ifdef DOMAIN_ALLOW_MALLOC_OVERRIDE
|
||||
#include "/usr/include/apollo/shlib.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#define X_INCLUDE_PWD_H
|
||||
#define XOS_USE_XT_LOCKING
|
||||
#include <X11/Xos_r.h>
|
||||
#include <codelibs/nl_hack.h>
|
||||
|
||||
#ifdef apollo
|
||||
// This kludge because of include conflicts between stdlib.h and unistd.h
|
||||
// Remove when problem is fixed
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
# endif
|
||||
_DECL_FUNC(__pid_t, getpid, (void))
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif
|
||||
#else /* not apollo */
|
||||
# include <unistd.h>
|
||||
#endif /* not apollo */
|
||||
|
||||
#include "stringio.h"
|
||||
#include "buf.h"
|
||||
#include <codelibs/shellutils.h>
|
||||
|
||||
#include <codelibs/boolean.h>
|
||||
#include <codelibs/stringx.h>
|
||||
#include "DtSvcLock.h"
|
||||
|
||||
#ifdef XTHREADS
|
||||
extern "C" {
|
||||
extern void XtProcessLock(void);
|
||||
extern void XtProcessUnlock(void);
|
||||
}
|
||||
#endif
|
||||
|
||||
#define ISIDENT(CH) (isalnum(CH) || (CH) == '_')
|
||||
|
||||
static _SHXbuf *buf = NULL;
|
||||
static const char *getvar(const char *var, char *);
|
||||
|
||||
// Make this a global someday:
|
||||
static const char *(*shellvarfn)(const char *, char *) = getvar;
|
||||
|
||||
// Parse a sequence of the ksh meta-characters ;&|<> and whitespace
|
||||
// into a single ksh token. Return a pointer to the token as a
|
||||
// string. All whitespace characters are mapped to a single space
|
||||
// character. If ch is not a meta-character, return a NULL pointer.
|
||||
static char *
|
||||
parsemeta(int ch, _StringIO &in, char *ifs, unsigned opts, char *meta)
|
||||
{
|
||||
if (ch == '\0')
|
||||
return " "; // whitespace
|
||||
|
||||
_DtSvcProcessLock();
|
||||
if (buf->quote() != NOQUOTE) {
|
||||
_DtSvcProcessUnlock();
|
||||
return NULL; // normal character
|
||||
}
|
||||
|
||||
if (!(opts & SHX_NOSPACE) && strchr(ifs, ch) != NULL) {
|
||||
_DtSvcProcessUnlock();
|
||||
return " "; // whitespace
|
||||
}
|
||||
|
||||
if (!(opts & SHX_NOMETA))
|
||||
{
|
||||
int len = 0;
|
||||
|
||||
if (buf->new_token() && isascii(ch) && isdigit(ch))
|
||||
if (in.next() == '<' || in.next() == '>')
|
||||
{
|
||||
meta[len++] = (char)ch;
|
||||
ch = in.get();
|
||||
}
|
||||
|
||||
switch (meta[len++] = (char)ch, ch)
|
||||
{
|
||||
case ';':
|
||||
case '&':
|
||||
case '(':
|
||||
case ')':
|
||||
meta[len++] = (in.next() == ch) ? in.get() : '\0';
|
||||
meta[len] = '\0';
|
||||
_DtSvcProcessUnlock();
|
||||
return meta;
|
||||
case '|':
|
||||
meta[len++] = (in.next() == '|' || in.next() == '&') ?
|
||||
in.get() : '\0';
|
||||
meta[len] = '\0';
|
||||
_DtSvcProcessUnlock();
|
||||
return meta;
|
||||
case '>':
|
||||
case '<':
|
||||
if (in.next() == ch || in.next() == '&')
|
||||
meta[len++] = (char)in.get();
|
||||
meta[len] = '\0';
|
||||
_DtSvcProcessUnlock();
|
||||
return meta;
|
||||
}
|
||||
}
|
||||
|
||||
_DtSvcProcessUnlock();
|
||||
return NULL; // normal character
|
||||
}
|
||||
|
||||
// Takes the name of a variable, and looks up it's value. Someday,
|
||||
// this will be replaceable by the user.
|
||||
static const char *
|
||||
getvar(const char *name, char *buff)
|
||||
{
|
||||
if (name[0] != '\0' && name[1] == '\0')
|
||||
switch (name[0])
|
||||
{
|
||||
case '$':
|
||||
sprintf(buff, "%d", getpid());
|
||||
return buff;
|
||||
case '#':
|
||||
case '?':
|
||||
return "0";
|
||||
}
|
||||
|
||||
return getenv(name);
|
||||
}
|
||||
|
||||
// Parse an environment variable name from the _StringIO stream,
|
||||
// and push its value into the _StringIO stream stack.
|
||||
static boolean
|
||||
pushvar(_StringIO &in, char *buff)
|
||||
{
|
||||
_StringIO tmp;
|
||||
privbuf_charbuf name;
|
||||
|
||||
tmp = in;
|
||||
int ch = tmp.get(); // get the first character after the $
|
||||
|
||||
if (!isascii(ch))
|
||||
return FALSE;
|
||||
|
||||
if (ch == '{')
|
||||
while ((ch = tmp.get()) != '\0')
|
||||
{
|
||||
// ${foo!bar} form, grab everything inside {} as name
|
||||
if (ch == '\\') // Only \ does quoting inside ${}
|
||||
ch = tmp.get();
|
||||
else if (ch == '}')
|
||||
break;
|
||||
name.end() = ch;
|
||||
}
|
||||
else if (ispunct(ch))
|
||||
switch (ch) // Special non-alnum shell variables
|
||||
{
|
||||
case '#':
|
||||
case '?':
|
||||
case '$':
|
||||
case '!':
|
||||
case '-':
|
||||
case '*':
|
||||
case '@':
|
||||
case '_':
|
||||
name.end() = ch;
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
else if (isdigit(ch))
|
||||
name.end() = ch; // single-digit variables
|
||||
else if (ISIDENT(ch))
|
||||
{
|
||||
// normal variable
|
||||
do
|
||||
name.end() = ch;
|
||||
while (isascii(ch = tmp.get()) && ISIDENT(ch));
|
||||
tmp.unget();
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
|
||||
name.end() = '\0';
|
||||
|
||||
in = tmp;
|
||||
in.push(shellvarfn(name.getarr(), buff));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static boolean
|
||||
pushenv(_StringIO &in, char const *name)
|
||||
{
|
||||
register char *str = getenv(name);
|
||||
if (str == NULL || *str == '\0')
|
||||
return FALSE;
|
||||
else
|
||||
{
|
||||
in.push(str);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static boolean
|
||||
pushtilde(_StringIO &in)
|
||||
{
|
||||
_StringIO tmp;
|
||||
int namelen = 0;
|
||||
privbuf_charbuf name;
|
||||
|
||||
tmp = in;
|
||||
int ch;
|
||||
|
||||
while ((ch = tmp.get()) != '\0' && ch != '/')
|
||||
name[namelen++] = ch;
|
||||
name[namelen] = '\0';
|
||||
tmp.unget();
|
||||
|
||||
char *str = name.getarr();
|
||||
switch (*str)
|
||||
{
|
||||
case '\0':
|
||||
if (!pushenv(tmp, "HOME"))
|
||||
return FALSE;
|
||||
break;
|
||||
case '+':
|
||||
if (!pushenv(tmp, "PWD"))
|
||||
return FALSE;
|
||||
break;
|
||||
case '-':
|
||||
if (!pushenv(tmp, "OLDPWD"))
|
||||
return FALSE;
|
||||
break;
|
||||
default:
|
||||
{
|
||||
_Xgetpwparams pwd_buf;
|
||||
memset((char*) &pwd_buf, 0, sizeof(_Xgetpwparams));
|
||||
struct passwd * pwd_ret = _XGetpwnam(str, pwd_buf);
|
||||
|
||||
if (pwd_ret == NULL)
|
||||
return FALSE;
|
||||
tmp.push(pwd_ret->pw_dir);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
in = tmp;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
pushgrave(_StringIO &in, const char endchar, boolean quotes, privbuf_charbuf &result)
|
||||
{
|
||||
int ch;
|
||||
char quote = NOQUOTE;
|
||||
privbuf_charbuf cmd;
|
||||
|
||||
do
|
||||
{
|
||||
ch = in.get();
|
||||
|
||||
if (quotes)
|
||||
switch (ch)
|
||||
{
|
||||
case '"':
|
||||
quote = DOUBLEQUOTE;
|
||||
continue;
|
||||
case '\'':
|
||||
if (quote == '"')
|
||||
break; // not recognized inside of ""
|
||||
do
|
||||
cmd.end() = ch;
|
||||
while ((ch = in.get()) != '\'' && ch != '\0');
|
||||
cmd.end() = '\'';
|
||||
quote = NOQUOTE;
|
||||
continue;
|
||||
case '\\':
|
||||
cmd.end() = ch;
|
||||
ch = in.get();
|
||||
if (ch != '\0')
|
||||
cmd.end() = ch;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ch == endchar)
|
||||
ch = '\0';
|
||||
|
||||
cmd.end() = ch;
|
||||
} while (ch != '\0');
|
||||
|
||||
result.reset();
|
||||
|
||||
FILE *fp = popen(cmd.getarr(), "r");
|
||||
if (fp == NULL)
|
||||
return;
|
||||
while ((ch = getc(fp)) != EOF)
|
||||
result.end() = ch;
|
||||
pclose(fp);
|
||||
|
||||
// Remove trailing newline, if any
|
||||
long end = result.size() - 1;
|
||||
if (result[end] == '\n')
|
||||
result.reset(end);
|
||||
|
||||
result.end() = '\0';
|
||||
in.push(result.getarr());
|
||||
}
|
||||
|
||||
char const *const *
|
||||
shellscan(char const *str, int *argc, unsigned opts)
|
||||
{
|
||||
if (opts & SHX_COMPLETE)
|
||||
opts |= SHX_NOSPACE | SHX_NOMETA;
|
||||
|
||||
char *ifs = getenv("IFS");
|
||||
|
||||
if (ifs == NULL)
|
||||
ifs = " \t\n";
|
||||
|
||||
_DtSvcProcessLock();
|
||||
if (buf == NULL)
|
||||
buf = new _SHXbuf;
|
||||
buf->reset((boolean)!(opts & SHX_NOGLOB), (boolean)(opts & SHX_COMPLETE));
|
||||
|
||||
_StringIO in(str);
|
||||
int ch;
|
||||
char buff[10], meta_buff[4];
|
||||
privbuf_charbuf result;
|
||||
|
||||
do
|
||||
{
|
||||
ch = in.get();
|
||||
|
||||
// Don't recognize special characters if this is a shell
|
||||
// variable or command substitution.
|
||||
if (!in.in_expansion())
|
||||
{
|
||||
// Handle quoting rules, setting the flag array and
|
||||
// quote variable appropriately.
|
||||
if (!(opts & SHX_NOQUOTES))
|
||||
switch (ch)
|
||||
{
|
||||
case '"':
|
||||
buf->quote(DOUBLEQUOTE);
|
||||
continue;
|
||||
case '\'':
|
||||
if (buf->quote() == DOUBLEQUOTE)
|
||||
break; // not recognized inside of ""
|
||||
buf->quote(SINGLEQUOTE);
|
||||
while ((ch = in.get()) != '\'' && ch != '\0')
|
||||
buf->append(ch);
|
||||
buf->quote(SINGLEQUOTE);
|
||||
continue;
|
||||
case '\\':
|
||||
ch = in.get();
|
||||
if (ch == '\n') // ignore \<newline>
|
||||
continue;
|
||||
if (ch == '\0')
|
||||
{
|
||||
#if defined(__aix) /* Our Macro doesn't like '\\' (ignores rest of line) */
|
||||
buf->append('\\',
|
||||
SINGLEQUOTE);
|
||||
#else
|
||||
buf->append('\\', SINGLEQUOTE);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
if (buf->quote() == NOQUOTE)
|
||||
{
|
||||
buf->append(ch, SINGLEQUOTE);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// inside "", \ only quotes these 4 characters:
|
||||
switch (ch)
|
||||
{
|
||||
case '$':
|
||||
case '\\':
|
||||
case '`':
|
||||
case '"':
|
||||
buf->append(ch, SINGLEQUOTE);
|
||||
continue;
|
||||
default:
|
||||
// treat the \ and the following char normally
|
||||
buf->append('\\');
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(opts & SHX_NOCMD))
|
||||
switch (ch)
|
||||
{
|
||||
case '`':
|
||||
pushgrave(in, '`', (boolean)!(opts & SHX_NOQUOTES), result);
|
||||
continue;
|
||||
case '$':
|
||||
if (in.next() != '(')
|
||||
break;
|
||||
in.get(); // skip the '('
|
||||
pushgrave(in, ')', (boolean)!(opts & SHX_NOQUOTES), result);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ch == '~' && buf->new_token() && buf->quote() == NOQUOTE)
|
||||
if (!(opts & SHX_NOTILDE))
|
||||
{
|
||||
if (pushtilde(in))
|
||||
continue;
|
||||
buf->append('~');
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ch == '$' && !(opts & SHX_NOVARS))
|
||||
{
|
||||
if (pushvar(in, buff))
|
||||
continue;
|
||||
buf->append('$');
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// If the next item is an unquoted whitespace character or
|
||||
// metacharacter token, terminate the current token. The NUL
|
||||
// character is considered to be whitespace.
|
||||
{
|
||||
int curr_opts = opts;
|
||||
|
||||
if (in.in_expansion())
|
||||
curr_opts |= SHX_NOMETA;
|
||||
|
||||
char *meta = parsemeta(ch, in, ifs, curr_opts, meta_buff);
|
||||
|
||||
if (meta != NULL) // is it a meta-character?
|
||||
{
|
||||
// Terminate current token, if any
|
||||
if (!buf->new_token())
|
||||
buf->append('\0');
|
||||
if (*meta == ' ') // whitespace
|
||||
{
|
||||
// ignore contiguous whitespace chars
|
||||
if (buf->new_token())
|
||||
continue;
|
||||
}
|
||||
else // append the metachar token
|
||||
buf->append(meta);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
buf->append(ch);
|
||||
} while (ch != '\0');
|
||||
|
||||
if (argc != NULL)
|
||||
*argc = buf->ntokens();
|
||||
|
||||
_DtSvcProcessUnlock();
|
||||
return ( (char const *const *) buf->vector() );
|
||||
/* !!! error 1325: `)' missing at end of input */
|
||||
}
|
||||
46
cde/lib/DtSvc/DtCodelibs/strcase.C
Normal file
46
cde/lib/DtSvc/DtCodelibs/strcase.C
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* $XConsortium: strcase.C /main/4 1996/04/21 19:09:37 drk $
|
||||
*
|
||||
* (c) Copyright 1996 Digital Equipment Corporation.
|
||||
* (c) Copyright 1993,1994,1996 Hewlett-Packard Company.
|
||||
* (c) Copyright 1993,1994,1996 International Business Machines Corp.
|
||||
* (c) Copyright 1993,1994,1996 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993,1994,1996 Novell, Inc.
|
||||
* (c) Copyright 1996 FUJITSU LIMITED.
|
||||
* (c) Copyright 1996 Hitachi.
|
||||
*/
|
||||
|
||||
#include <codelibs/nl_hack.h>
|
||||
#include <codelibs/stringx.h>
|
||||
|
||||
char *strupper(char *str)
|
||||
{
|
||||
int len;
|
||||
|
||||
if (str != NULL)
|
||||
{
|
||||
for (register char *s = str; *s != '\0'; s++)
|
||||
if ((len = mblen(s, MB_CUR_MAX)) > 1)
|
||||
s += len;
|
||||
else
|
||||
*s = toupper((unsigned char)*s);
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
char *strlower(char *str)
|
||||
{
|
||||
int len;
|
||||
|
||||
if (str != NULL)
|
||||
{
|
||||
for (register char *s = str; *s != '\0'; s++)
|
||||
if ((len = mblen(s, MB_CUR_MAX)) > 1)
|
||||
s += len;
|
||||
else
|
||||
*s = tolower((unsigned char)*s);
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
24
cde/lib/DtSvc/DtCodelibs/strend.C
Normal file
24
cde/lib/DtSvc/DtCodelibs/strend.C
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* $XConsortium: strend.C /main/4 1996/04/21 19:09:40 drk $
|
||||
*
|
||||
* (c) Copyright 1996 Digital Equipment Corporation.
|
||||
* (c) Copyright 1993,1994,1996 Hewlett-Packard Company.
|
||||
* (c) Copyright 1993,1994,1996 International Business Machines Corp.
|
||||
* (c) Copyright 1993,1994,1996 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993,1994,1996 Novell, Inc.
|
||||
* (c) Copyright 1996 FUJITSU LIMITED.
|
||||
* (c) Copyright 1996 Hitachi.
|
||||
*/
|
||||
#include <codelibs/stringx.h>
|
||||
|
||||
char *
|
||||
strend(register const char *str)
|
||||
{
|
||||
if (str == NULL)
|
||||
return NULL;
|
||||
|
||||
while (*str != '\0')
|
||||
str++;
|
||||
|
||||
return (char *)str;
|
||||
}
|
||||
112
cde/lib/DtSvc/DtCodelibs/strhash.C
Normal file
112
cde/lib/DtSvc/DtCodelibs/strhash.C
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* $XConsortium: strhash.C /main/5 1996/06/21 17:36:23 ageorge $
|
||||
*
|
||||
* (c) Copyright 1996 Digital Equipment Corporation.
|
||||
* (c) Copyright 1993,1994,1996 Hewlett-Packard Company.
|
||||
* (c) Copyright 1993,1994,1996 International Business Machines Corp.
|
||||
* (c) Copyright 1993,1994,1996 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993,1994,1996 Novell, Inc.
|
||||
* (c) Copyright 1996 FUJITSU LIMITED.
|
||||
* (c) Copyright 1996 Hitachi.
|
||||
*/
|
||||
|
||||
#include <codelibs/nl_hack.h>
|
||||
#include <codelibs/stringx.h>
|
||||
|
||||
|
||||
/**************************************************
|
||||
// This is quick but does a pretty crummy job
|
||||
unsigned strhash(register const unsigned char *key)
|
||||
{
|
||||
register unsigned hash = 0;
|
||||
while (*key != '\0')
|
||||
hash = (hash << 3) + *key++;
|
||||
return hash;
|
||||
}
|
||||
**************************************************/
|
||||
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#define BITS(type) (CHAR_BIT * (int)sizeof(type))
|
||||
|
||||
// This is from the "dragon" Compilers book.
|
||||
// It is much better than the above but somewhat slower.
|
||||
//
|
||||
unsigned strhash(register const char *p)
|
||||
{
|
||||
register unsigned h = 0;
|
||||
register unsigned g;
|
||||
wchar_t __nlh_char[1];
|
||||
|
||||
if (p != NULL)
|
||||
while (*p != '\0')
|
||||
{
|
||||
h = (h << 4) + (unsigned)CHARADV(p);
|
||||
if (g = h & ((unsigned)0xF << BITS(unsigned) - 4))
|
||||
{
|
||||
h ^= g >> BITS(unsigned) - 4;
|
||||
h ^= g;
|
||||
}
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
// Same as above but case insensitive. Returns the same value as the
|
||||
// above function if there are no upper case letters in the string.
|
||||
//
|
||||
unsigned strhashi(register const char *p)
|
||||
{
|
||||
register unsigned h = 0;
|
||||
register unsigned g;
|
||||
wchar_t __nlh_char[1];
|
||||
|
||||
if (p != NULL)
|
||||
while (*p != '\0')
|
||||
{
|
||||
if (mblen(p, MB_CUR_MAX) > 1)
|
||||
h = (h << 4) + (unsigned)CHARADV(p);
|
||||
else
|
||||
{
|
||||
h = (h << 4) + (unsigned)tolower(*p++);
|
||||
}
|
||||
|
||||
if (g = h & ((unsigned)0xF << BITS(unsigned) - 4))
|
||||
{
|
||||
h ^= g >> BITS(unsigned) - 4;
|
||||
h ^= g;
|
||||
}
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************
|
||||
// This is about twice as slow as the above but
|
||||
// does a slightly better hash.
|
||||
// by TJ Merritt
|
||||
|
||||
unsigned int
|
||||
hashfunc(buf, len)
|
||||
register unsigned char *buf;
|
||||
register int len;
|
||||
{
|
||||
register unsigned int in;
|
||||
register unsigned int xor;
|
||||
register unsigned int t;
|
||||
|
||||
xor = len << 8;
|
||||
in = 0;
|
||||
|
||||
while (len-- > 0)
|
||||
{
|
||||
in <<= 8;
|
||||
in += *buf++;
|
||||
xor ^= in;
|
||||
t = ((xor & 0x3) << 29) | (xor >> 3);
|
||||
xor ^= t;
|
||||
}
|
||||
|
||||
return xor ^ (xor >> 16);
|
||||
}
|
||||
**************************************************/
|
||||
38
cde/lib/DtSvc/DtCodelibs/stringio.C
Normal file
38
cde/lib/DtSvc/DtCodelibs/stringio.C
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* File: stringio.C $XConsortium: stringio.C /main/5 1996/06/21 17:36:19 ageorge $
|
||||
*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993, 1994 Novell, Inc.
|
||||
*/
|
||||
#include <codelibs/nl_hack.h>
|
||||
#include "stringio.h"
|
||||
|
||||
int
|
||||
_StringIO::doit(register int commit)
|
||||
{
|
||||
register wchar_t ch;
|
||||
register int cu = curr;
|
||||
register char *ccp;
|
||||
wchar_t __nlh_char[1];
|
||||
|
||||
for (; cu >= 0; cu--)
|
||||
{
|
||||
ccp = ptr[cu];
|
||||
ch = ccp ? CHARAT(ccp) : '\0';
|
||||
if (ch != '\0')
|
||||
break;
|
||||
}
|
||||
if (commit)
|
||||
{
|
||||
old_curr = curr;
|
||||
if ((curr = cu) >= 0)
|
||||
{
|
||||
old_ccp = (const char *)ccp;
|
||||
ADVANCE(ccp);
|
||||
ptr[curr] = ccp;
|
||||
}
|
||||
}
|
||||
return ch;
|
||||
}
|
||||
75
cde/lib/DtSvc/DtCodelibs/stringio.h
Normal file
75
cde/lib/DtSvc/DtCodelibs/stringio.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* File: stringio.h $XConsortium: stringio.h /main/3 1995/10/26 16:10:00 rswiston $
|
||||
*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993, 1994 Novell, Inc.
|
||||
*/
|
||||
#include <codelibs/boolean.h>
|
||||
#define __PRIVATE_
|
||||
#include <codelibs/privbuf.h>
|
||||
|
||||
class _StringIO
|
||||
{
|
||||
privbuf_strvec ptr;
|
||||
int curr;
|
||||
int old_curr;
|
||||
char const *old_ccp;
|
||||
int doit(int commit);
|
||||
public:
|
||||
void push(char const *ccp);
|
||||
_StringIO();
|
||||
_StringIO(char const *ccp);
|
||||
void unget();
|
||||
int get();
|
||||
int next();
|
||||
boolean in_expansion();
|
||||
};
|
||||
|
||||
inline
|
||||
_StringIO::_StringIO()
|
||||
{
|
||||
curr = old_curr = -1;
|
||||
old_ccp = 0;
|
||||
}
|
||||
|
||||
inline void
|
||||
_StringIO::push(char const *ccp)
|
||||
{
|
||||
ptr[++curr] = (char*)ccp;
|
||||
}
|
||||
|
||||
inline
|
||||
_StringIO::_StringIO(char const *ccp)
|
||||
{
|
||||
curr = old_curr = -1;
|
||||
old_ccp = 0;
|
||||
push(ccp);
|
||||
}
|
||||
|
||||
inline void
|
||||
_StringIO::unget()
|
||||
{
|
||||
if (curr >= 0)
|
||||
ptr[curr] = (char*)old_ccp;
|
||||
curr = old_curr;
|
||||
}
|
||||
|
||||
inline int
|
||||
_StringIO::get()
|
||||
{
|
||||
return doit(1);
|
||||
}
|
||||
|
||||
inline int
|
||||
_StringIO::next()
|
||||
{
|
||||
return doit(0);
|
||||
}
|
||||
|
||||
inline boolean
|
||||
_StringIO::in_expansion()
|
||||
{
|
||||
return ((boolean)(curr > 0));
|
||||
}
|
||||
46
cde/lib/DtSvc/DtCodelibs/strtokx.C
Normal file
46
cde/lib/DtSvc/DtCodelibs/strtokx.C
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* $XConsortium: strtokx.C /main/4 1996/04/21 19:09:46 drk $
|
||||
*
|
||||
* (c) Copyright 1996 Digital Equipment Corporation.
|
||||
* (c) Copyright 1993,1994,1996 Hewlett-Packard Company.
|
||||
* (c) Copyright 1993,1994,1996 International Business Machines Corp.
|
||||
* (c) Copyright 1993,1994,1996 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993,1994,1996 Novell, Inc.
|
||||
* (c) Copyright 1996 FUJITSU LIMITED.
|
||||
* (c) Copyright 1996 Hitachi.
|
||||
*/
|
||||
#include <codelibs/nl_hack.h>
|
||||
#include <codelibs/mbstring.h>
|
||||
#include <codelibs/stringx.h>
|
||||
|
||||
char *
|
||||
strtokx(register char *&ptr, register const char *sep)
|
||||
{
|
||||
if (ptr == NULL)
|
||||
return NULL;
|
||||
|
||||
// find the beginning of the token
|
||||
register char *ret = ptr;
|
||||
while (*ret != '\0' && _mb_schr(sep, *ret) != NULL)
|
||||
ADVANCE(ret);
|
||||
|
||||
// find the end of the token
|
||||
register char *end = ret;
|
||||
while (*end != '\0' && _mb_schr(sep, *end) == NULL)
|
||||
ADVANCE(end);
|
||||
|
||||
ptr = end;
|
||||
|
||||
// If this isn't the last token, advance pointer and terminate
|
||||
// current token.
|
||||
if (*end != '\0')
|
||||
{
|
||||
ADVANCE(ptr);
|
||||
WCHAR('\0', end);
|
||||
}
|
||||
|
||||
if (*ret == '\0')
|
||||
return NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
283
cde/lib/DtSvc/DtCodelibs/strwcmp.C
Normal file
283
cde/lib/DtSvc/DtCodelibs/strwcmp.C
Normal file
@@ -0,0 +1,283 @@
|
||||
/*
|
||||
* $TOG: strwcmp.C /main/7 1998/04/17 11:25:04 mgreess $
|
||||
*
|
||||
* (c) Copyright 1996 Digital Equipment Corporation.
|
||||
* (c) Copyright 1993,1994,1996 Hewlett-Packard Company.
|
||||
* (c) Copyright 1993,1994,1996 International Business Machines Corp.
|
||||
* (c) Copyright 1993,1994,1996 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993,1994,1996 Novell, Inc.
|
||||
* (c) Copyright 1996 FUJITSU LIMITED.
|
||||
* (c) Copyright 1996 Hitachi.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <codelibs/nl_hack.h>
|
||||
#include <string.h>
|
||||
#include <codelibs/stringx.h>
|
||||
|
||||
#define QUOTE 0x40000000
|
||||
|
||||
#ifdef DEBUG
|
||||
static char tabs[] = " ";
|
||||
# define TABS (&tabs[10 - depth])
|
||||
|
||||
static int
|
||||
RETURN(int ret, int depth)
|
||||
{
|
||||
printf("%sreturning %s\n", TABS,
|
||||
(ret ? "SUCCEEDED" : "FAILED"));
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
#define RETURN(x,y) (x)
|
||||
#endif
|
||||
|
||||
/* FORWARD */
|
||||
static int match(const char *, const char *, int);
|
||||
static const char *next_patt(const char *, int advance = 1);
|
||||
static int match_class(const char *, char);
|
||||
|
||||
/* INLINE */
|
||||
static int
|
||||
next_char(register const char *pattern, const char **cpp = NULL)
|
||||
{
|
||||
register int ret;
|
||||
wchar_t __nlh_char[1];
|
||||
|
||||
ret = pattern ? (int)CHARAT(pattern) : '\0';
|
||||
if (ret != '\0')
|
||||
{
|
||||
ADVANCE(pattern);
|
||||
/* AIX needs line broken to get around macro bug (Temporary Fix) */
|
||||
if (ret == '\\' &&
|
||||
CHARAT(pattern) != '\0')
|
||||
ret = QUOTE | (int)CHARADV(pattern);
|
||||
}
|
||||
|
||||
if (cpp != NULL)
|
||||
*cpp = pattern;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
strwcmp(const char *pattern, const char *string)
|
||||
/*
|
||||
* String 'pattern' is matched against string 'string'. Zero is
|
||||
* returned if the match is successful. 'pattern' may contain the
|
||||
* shell metas * and ? and the semantics are the same. ? and * may
|
||||
* be escaped with \
|
||||
*/
|
||||
{
|
||||
return !match(pattern, string, 0);
|
||||
}
|
||||
|
||||
// stwpat returns a pointer to the first meta-character if the string
|
||||
// is a pattern, else NULL
|
||||
char *
|
||||
strwpat(register const char *pattern)
|
||||
{
|
||||
register int ch;
|
||||
register char *prev_pattern = (char *)pattern;
|
||||
wchar_t __nlh_char[1];
|
||||
|
||||
while ((ch = next_char(pattern, &pattern)) != '\0')
|
||||
{
|
||||
switch (ch)
|
||||
{
|
||||
case '*':
|
||||
return prev_pattern;
|
||||
case '?':
|
||||
return prev_pattern;
|
||||
case '[': {
|
||||
register const char *eop = next_patt(prev_pattern, 0);
|
||||
if (CHARAT(eop) == ']')
|
||||
return prev_pattern;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
prev_pattern = (char *)pattern;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* match will check to see if pattern can successfully be applied to
|
||||
* the beginning of string.
|
||||
*/
|
||||
static int
|
||||
match(register const char *pattern, register const char *string, int depth)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("%smatch(\"%s\", \"%s\")\n", TABS, pattern, string);
|
||||
#endif
|
||||
int ch;
|
||||
const char *cp;
|
||||
wchar_t __nlh_char[1];
|
||||
|
||||
while ((ch = next_char(pattern, &cp)) != '\0')
|
||||
{
|
||||
const char *laststr = string;
|
||||
register int testchar = (int)CHARADV(string);
|
||||
|
||||
switch (ch)
|
||||
{
|
||||
case '*': {
|
||||
pattern = cp; /* skip over '*' */
|
||||
string = laststr; /* reverse - testchar not used */
|
||||
|
||||
const char *s = string;
|
||||
do
|
||||
if (match(pattern, s, depth + 1))
|
||||
return RETURN(1, depth);
|
||||
while (CHARADV(s) != '\0');
|
||||
return RETURN(0, depth);
|
||||
}
|
||||
case '?':
|
||||
break;
|
||||
case '[': {
|
||||
int mt = match_class(pattern, testchar);
|
||||
if (mt == 0)
|
||||
return RETURN(0, depth);
|
||||
else if (mt == 2 && ch != testchar)
|
||||
return RETURN(0, depth);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
if ((ch & ~QUOTE) != testchar)
|
||||
return RETURN(0, depth);
|
||||
break;
|
||||
}
|
||||
|
||||
if (testchar == '\0')
|
||||
string = laststr; // reverse string
|
||||
|
||||
pattern = next_patt(pattern);
|
||||
}
|
||||
|
||||
return RETURN(CHARAT(string) == '\0', depth);
|
||||
}
|
||||
|
||||
static int
|
||||
match_class(register const char *clss, register char testchar)
|
||||
/*
|
||||
* pattern is a pointer to the leading [ of
|
||||
* a shell-type class. testchar is the character to match against
|
||||
* the class.
|
||||
*/
|
||||
{
|
||||
int match = 1; /* false if first char is '!' */
|
||||
wchar_t __nlh_char[1];
|
||||
|
||||
/* find end of class, ie an un-escaped ']' */
|
||||
register const char *eop = next_patt(clss, 0);
|
||||
ADVANCE(clss);
|
||||
|
||||
if (CHARAT(eop) != ']')
|
||||
return 2;
|
||||
|
||||
if (CHARAT(clss) == '!')
|
||||
{
|
||||
match = 0;
|
||||
ADVANCE(clss);
|
||||
}
|
||||
|
||||
while (clss < eop)
|
||||
{
|
||||
register int ch = next_char(clss, &clss);
|
||||
char const *clss_end = clss;
|
||||
int sep = next_char(clss_end, &clss_end);
|
||||
int ch2 = next_char(clss_end, &clss_end);
|
||||
|
||||
/* check if next three chars are a range */
|
||||
if (sep == '-' && ch2 != ']')
|
||||
{
|
||||
/* check range - we have to use strcoll to do it right */
|
||||
char c1[MB_LEN_MAX+1], c2[MB_LEN_MAX+1], tc[MB_LEN_MAX+1];
|
||||
memset(c1, 0, sizeof(c1));
|
||||
memset(c2, 0, sizeof(c2));
|
||||
memset(tc, 0, sizeof(tc));
|
||||
ch &= ~QUOTE;
|
||||
WCHAR(ch, c1);
|
||||
ch2 &= ~QUOTE;
|
||||
WCHAR(ch2, c2);
|
||||
WCHAR(testchar, tc);
|
||||
|
||||
/* if (ch <= testchar && testchar <= ch2) // Original code */
|
||||
|
||||
/* Second implementation:
|
||||
* if (nl_strncmp(c1, tc, 1) <= 0 && nl_strncmp(tc, c2, 1) <= 0)
|
||||
* return match;
|
||||
*/
|
||||
|
||||
/* Third, portable implementation: */
|
||||
if (strcoll(c1, tc) <= 0 && strcoll(tc, c2) <= 0)
|
||||
return match;
|
||||
clss = clss_end;
|
||||
}
|
||||
else /* they are not a range, check simple
|
||||
match */
|
||||
{
|
||||
if ((ch & ~QUOTE) == testchar)
|
||||
return match;
|
||||
}
|
||||
}
|
||||
|
||||
return !match;
|
||||
}
|
||||
|
||||
static const char *
|
||||
next_patt(register const char *pattern, int advance)
|
||||
{
|
||||
wchar_t __nlh_char[1];
|
||||
|
||||
if (CHARAT(pattern) == '[')
|
||||
{
|
||||
int ch;
|
||||
const char *pp = pattern;
|
||||
ADVANCE(pp);
|
||||
|
||||
if (CHARAT(pp) == '^')
|
||||
ADVANCE(pp);
|
||||
|
||||
if (CHARAT(pp) == ']')
|
||||
ADVANCE(pp);
|
||||
|
||||
char const *np;
|
||||
for (; (ch = next_char(pp, &np)) != '\0'; pp = np)
|
||||
if (ch == ']')
|
||||
return (advance ? np : pp);
|
||||
}
|
||||
|
||||
next_char(pattern, &pattern);
|
||||
return pattern;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
#define MAIN main
|
||||
MAIN()
|
||||
{
|
||||
char pattern[50], string[50];
|
||||
|
||||
while (1)
|
||||
{
|
||||
putchar('\n');
|
||||
printf("pattern: ");
|
||||
if (fgets(pattern, sizeof(pattern)-1, stdin) == NULL)
|
||||
break;
|
||||
printf("string: ");
|
||||
if (fgets(string, sizeof(pattern)-1, stdin) == NULL)
|
||||
break;
|
||||
printf("MATCH is %s\n",
|
||||
((strwcmp(pattern, string) == 0) ? "SUCCEEDED" : "FAILED"));
|
||||
putchar('\n');
|
||||
printf("MATCHI is %s\n",
|
||||
((strwcmpi(pattern, string) == 0) ? "SUCCEEDED" : "FAILED"));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user