home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 2002 July
/
VPR0207A.ISO
/
OLS
/
UNRAR32007
/
unrar32007.lzh
/
src.lzh
/
src
/
util.cxx
< prev
next >
Wrap
C/C++ Source or Header
|
2001-02-16
|
7KB
|
338 lines
/*
* Copyright (c) 1998-2001 T. Kamei (kamei@jsdlab.co.jp)
*
* Permission to use, copy, modify, and distribute this software
* and its documentation for any purpose is hereby granted provided
* that the above copyright notice and this permission notice appear
* in all copies of the software and related documentation.
*
* NO WARRANTY
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY WARRANTIES;
* WITHOUT EVEN THE IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS
* FOR A PARTICULAR PURPOSE.
*/
#include <windows.h>
#include <stdio.h>
#include "comm-arc.h"
#include "util.h"
#include "mapf.h"
void
init_table ()
{
for (int i = 0; i < 256; i++)
{
translate_table[i] = i;
mblead_table[i] = IsDBCSLeadByte (i);
}
for (i = 'a'; i <= 'z'; i++)
translate_table[i] = i - 'a' + 'A';
}
#define SEPCHAR_P(C) ((C) == '/' || (C) == '\\')
char *
find_last_slash (const char *p)
{
for (u_char *x = 0, *s = (u_char *)p; *s;)
{
#ifdef KANJI
if (iskanji (*s) && s[1])
s += 2;
else
#endif
{
if (SEPCHAR_P (*s))
x = s;
s++;
}
}
return (char *)x;
}
char *
find_slash (const char *p)
{
for (u_char *s = (u_char *)p; *s;)
{
#ifdef KANJI
if (iskanji (*s) && s[1])
s += 2;
else
#endif
{
if (SEPCHAR_P (*s))
return (char *)s;
s++;
}
}
return 0;
}
char *
trim_root (const char *path)
{
if (isalpha (u_char (*path)) && path[1] == ':')
path += 2;
for (; SEPCHAR_P (*path); path++)
;
return (char *)path;
}
char *
stpcpy (char *d, const char *s)
{
int l = strlen (s);
memcpy (d, s, l + 1);
return d + l;
}
void
cmdline::discard ()
{
for (int i = 0; i < cl_ac; i++)
if (cl_av[i])
free (cl_av[i]);
if (cl_av)
free (cl_av);
cl_ac = 0;
cl_av = 0;
cl_max = 0;
}
char *
cmdline::copyarg (const u_char *s, const u_char *se, int dq)
{
int l = se - s - dq;
if (!l)
return "";
char *d0 = (char *)malloc (l + 1);
if (!d0)
return 0;
for (char *d = d0; s < se; s++)
if (*s != '"')
*d++ = *s;
*d = 0;
return d0;
}
int
cmdline::parse (const char *cmdline, int l, int resp_ok)
{
if (!cmdline)
return 0;
const u_char *cp = (const u_char *)cmdline;
const u_char *ce = cp + l;
const u_char *c0 = 0;
int dq = 0;
for (;; cp++)
{
int c = cp == ce ? EOF : *cp;
switch (c)
{
case ' ':
case '\t':
if (dq & 1)
goto normal_char;
/* fall thru... */
case EOF:
case '\r':
case '\n':
if (c0)
{
char *arg = copyarg (c0, cp, dq);
if (!arg)
return ERROR_ENOUGH_MEMORY;
if (resp_ok && *arg == '@')
{
mapf mf;
int e = mf.open (arg + 1);
free (arg);
if (!e)
return ERROR_RESPONSE_READ;
e = parse ((const char *)mf.base (), mf.size (), 0);
if (e)
return e;
}
else if (*arg)
{
if (cl_ac == cl_max)
{
cl_max += 32;
char **x = (char **)realloc (cl_av, sizeof *x * cl_max);
if (!x)
{
free (arg);
return ERROR_ENOUGH_MEMORY;
}
cl_av = x;
}
cl_av[cl_ac++] = arg;
}
dq = 0;
c0 = 0;
}
if (c == EOF)
return 0;
break;
case '"':
dq++;
/* fall thru... */
default:
normal_char:
if (!c0)
c0 = cp;
break;
}
}
}
int
glob::match (const char *pat, const char *str, int recursive)
{
const u_char *p = (const u_char *)pat;
const u_char *s = (const u_char *)str;
while (1)
{
int c = *p++;
switch (c)
{
case 0:
return !*s || (recursive && SEPCHAR_P (*s));
case '?':
if (!*s || SEPCHAR_P (*s))
return 0;
#ifdef KANJI
if (iskanji (*s) && s[1])
s++;
#endif
s++;
break;
case '*':
for (; *p == '*'; p++)
;
if (!*p)
return recursive || !find_slash ((const char *)s);
while (1)
{
if (match ((const char *)p, (const char *)s, recursive))
return 1;
if (!*s || SEPCHAR_P (*s))
return 0;
#ifdef KANJI
if (iskanji (*s) && s[1])
s++;
#endif
s++;
}
case '/':
case '\\':
if (!SEPCHAR_P (*s))
return 0;
s++;
break;
default:
#ifdef KANJI
if (iskanji (c) && *p)
{
if (u_char (c) != *s++)
return 0;
if (*p++ != *s++)
return 0;
}
else
#endif
{
if (translate (c) != translate (*s))
return 0;
s++;
}
}
}
}
int
glob::match (const char *file, int strict, int recursive) const
{
if (!g_npat)
return 1;
if (strict)
{
for (int i = 0; i < g_npat; i++)
if (match (g_pat[i], file, recursive))
return 1;
}
else
{
const char *name = find_last_slash (file);
name = name ? name + 1 : file;
for (int i = 0; i < g_npat; i++)
if (match (g_pat[i], find_slash (g_pat[i]) ? file : name, recursive))
return 1;
}
return 0;
}
void
glob::set_pattern (int ac, char **av)
{
g_npat = ac;
g_pat = av;
for (int i = 0; i < g_npat; i++)
{
char *p = find_last_slash (g_pat[i]);
if (p && !p[1])
*p = 0;
}
}
int
check_kanji_trail (const char *string, u_int off)
{
for (const u_char *s0 = (u_char *)string, *se = s0 + off, *s = se;
s-- > s0 && iskanji (*s);)
;
return !((se - s) & 1);
}
int
ostrbuf::formatv (const char *fmt, va_list ap)
{
if (space () <= 0)
return 0;
int l = _vsnprintf (os_buf, space (), fmt, ap);
if (l > 0)
{
os_buf += l;
os_size -= l;
*os_buf = 0;
}
else
{
l = space ();
if (check_kanji_trail (os_buf, l))
l--;
os_buf[l] = 0;
os_size = 0;
}
return space () > 0;
}
int
ostrbuf::format (const char *fmt, ...)
{
va_list ap;
va_start (ap, fmt);
int x = formatv (fmt, ap);
va_end (ap);
return x;
};