2f8a60 | 2001-06-10 | Henrik Grubbström (Grubba) | | |
dd1072 | 2001-09-24 | Fredrik Hübinette (Hubbe) | | * $Id: combine_path.h,v 1.9 2001/09/25 03:13:23 hubbe Exp $
|
2f8a60 | 2001-06-10 | Henrik Grubbström (Grubba) | | *
* Combine path template.
*
*/
|
8e0678 | 2001-06-07 | Fredrik Hübinette (Hubbe) | | #undef IS_SEP
#undef IS_ABS
#undef IS_ROOT
#undef F_COMBINE_PATH
#undef APPEND_PATH
#define COMBINE_PATH_DEBUG 0
#ifdef UNIX_COMBINE_PATH
#define IS_SEP(X) ( (X)=='/' )
#define IS_ABS(X) (IS_SEP( INDEX_PCHARP((X),0))?1:0)
#define APPEND_PATH append_path_unix
#define F_COMBINE_PATH f_combine_path_unix
#endif /* UNIX_COMBINE_PATH */
#ifdef NT_COMBINE_PATH
#define IS_SEP(X) ( (X) == '/' || (X) == '\\' )
static int find_absolute(PCHARP s)
{
int c0=INDEX_PCHARP(s,0);
int c1=c0?INDEX_PCHARP(s,1):0;
if(isalpha(c0) && c1==':' && IS_SEP(INDEX_PCHARP(s,2)))
return 3;
if(IS_SEP(c0) && IS_SEP(c1))
{
int l;
|
dd1072 | 2001-09-24 | Fredrik Hübinette (Hubbe) | | for(l=2;INDEX_PCHARP(s,l) && !IS_SEP(INDEX_PCHARP(s,l));l++);
|
8e0678 | 2001-06-07 | Fredrik Hübinette (Hubbe) | | return l;
}
return 0;
}
#define IS_ABS(X) find_absolute((X))
#define IS_ROOT(X) ( IS_SEP( INDEX_PCHARP((X),0) )?1:0)
#define APPEND_PATH append_path_nt
#define F_COMBINE_PATH f_combine_path_nt
#endif /* NT_COMBINE_PATH */
static void APPEND_PATH(struct string_builder *s,
PCHARP path,
size_t len)
{
size_t from=0;
|
1f88bf | 2001-09-24 | Henrik Grubbström (Grubba) | | int tmp;
|
8e0678 | 2001-06-07 | Fredrik Hübinette (Hubbe) | | int abs=0;
abs=IS_ABS(MKPCHARP_STR(s->s));
if((tmp=IS_ABS(path)))
{
s->s->len=0;
s->known_shift=0;
string_builder_append(s, path, tmp);
from+=tmp;
abs++;
}
#ifdef IS_ROOT
else if((tmp=IS_ROOT(path)))
{
int tmp2;
abs++;
s->known_shift=0;
if((tmp2=IS_ABS(MKPCHARP_STR(s->s))))
{
s->s->len=tmp2;
}else{
s->s->len=0;
string_builder_append(s, path, tmp);
}
from+=tmp;
}
#endif
#define LAST_PUSHED() (s->s->len ? index_shared_string(s->s,s->s->len-1) : 0)
#define PUSH(X) string_builder_putchar(s,(X))
|
2f8a60 | 2001-06-10 | Henrik Grubbström (Grubba) | |
|
8e0678 | 2001-06-07 | Fredrik Hübinette (Hubbe) | | if(s->s->len && !IS_SEP(LAST_PUSHED()))
PUSH('/');
|
279f6a | 2001-06-11 | Henrik Grubbström (Grubba) | | if (!len) return;
|
2f8a60 | 2001-06-10 | Henrik Grubbström (Grubba) | |
|
913b26 | 2001-06-10 | Henrik Grubbström (Grubba) | | if(s->s->len==2)
|
8e0678 | 2001-06-07 | Fredrik Hübinette (Hubbe) | | {
PCHARP to=MKPCHARP_STR(s->s);
if(INDEX_PCHARP(to, 0) == '.')
{
s->s->len=0;
s->known_shift=0;
}
}
while(1)
{
#if COMBINE_PATH_DEBUG > 1
s->s->str[s->s->len]=0;
|
2f8a60 | 2001-06-10 | Henrik Grubbström (Grubba) | | fprintf(stderr, "combine_path(2), TO: \"%s\"\n", s->s->str);
fprintf(stderr, "combine_path(2), FROM (%d): \"%s\"\n",
from, path.ptr+from);
|
8e0678 | 2001-06-07 | Fredrik Hübinette (Hubbe) | | #endif
if(IS_SEP(LAST_PUSHED()))
{
while(s->s->len && IS_SEP(LAST_PUSHED()))
s->s->len--;
PUSH('/');
if(from<len && INDEX_PCHARP(path, from) == '.')
{
int c3;
#if COMBINE_PATH_DEBUG > 0
s->s->str[s->s->len]=0;
|
2f8a60 | 2001-06-10 | Henrik Grubbström (Grubba) | | fprintf(stderr, "combine_path(0), TO: \"%s\"\n", s->s->str);
fprintf(stderr, "combine_path(0), FROM (%d): \"%s\"\n",
from, path.ptr+from);
|
8e0678 | 2001-06-07 | Fredrik Hübinette (Hubbe) | | #endif
switch(INDEX_PCHARP(path, from+1))
{
case '.':
c3=INDEX_PCHARP(path, from+2);
if(IS_SEP(c3) || !c3)
{
|
2f8a60 | 2001-06-10 | Henrik Grubbström (Grubba) | |
|
8e0678 | 2001-06-07 | Fredrik Hübinette (Hubbe) | | int tmp=s->s->len-1;
|
2f8a60 | 2001-06-10 | Henrik Grubbström (Grubba) | | if (tmp) {
while(--tmp>=0)
if(IS_SEP(index_shared_string(s->s, tmp)))
break;
tmp++;
} else if (IS_SEP(index_shared_string(s->s, 0))) {
tmp++;
}
|
8e0678 | 2001-06-07 | Fredrik Hübinette (Hubbe) | |
|
dbe48f | 2001-06-10 | Henrik Grubbström (Grubba) | | if ((tmp+1 < s->s->len) &&
|
7ebc3e | 2001-06-10 | Henrik Grubbström (Grubba) | | (index_shared_string(s->s,tmp)=='.') &&
(index_shared_string(s->s,tmp+1)=='.') &&
|
dbe48f | 2001-06-10 | Henrik Grubbström (Grubba) | | ( (tmp+2 == s->s->len) ||
|
61fdf5 | 2001-06-10 | Henrik Grubbström (Grubba) | | IS_SEP(index_shared_string(s->s,tmp+2))))
|
8e0678 | 2001-06-07 | Fredrik Hübinette (Hubbe) | | break;
from+=2;
s->s->len=tmp;
s->known_shift=0;
#if COMBINE_PATH_DEBUG > 0
s->s->str[s->s->len]=0;
fprintf(stderr,"combine_path(1), TO: %s\n",s->s->str);
fprintf(stderr,"combine_path(1), FROM (%d): %s\n",from,path.ptr+from);
#endif
continue;
}
break;
case 0:
case '/':
#ifdef NT_COMBINE_PATH
case '\\':
#endif
|
2f8a60 | 2001-06-10 | Henrik Grubbström (Grubba) | |
from++;
continue;
|
8e0678 | 2001-06-07 | Fredrik Hübinette (Hubbe) | | }
}
}
if(from>=len) break;
PUSH(INDEX_PCHARP(path, from++));
}
|
913b26 | 2001-06-10 | Henrik Grubbström (Grubba) | | if((s->s->len > 1) &&
|
8e0678 | 2001-06-07 | Fredrik Hübinette (Hubbe) | | !IS_SEP(INDEX_PCHARP(path, from-1)) &&
IS_SEP(LAST_PUSHED()))
s->s->len--;
if(!s->s->len)
{
if(abs)
{
PUSH('/');
}else{
PUSH('.');
}
}
}
void F_COMBINE_PATH(INT32 args)
{
int e;
int root=0;
struct string_builder ret;
ONERROR tmp;
check_all_args("combine_path",args,BIT_STRING, BIT_STRING | BIT_MANY | BIT_VOID, 0);
init_string_builder(&ret, 0);
SET_ONERROR(tmp, free_string_builder, &ret);
for(e=args-1;e>root;e--)
{
if(IS_ABS(MKPCHARP_STR(Pike_sp[e-args].u.string)))
{
root=e;
break;
}
}
APPEND_PATH(&ret,
MKPCHARP_STR(Pike_sp[root-args].u.string),
Pike_sp[root-args].u.string->len);
root++;
#ifdef IS_ROOT
for(e=args-1;e>root;e--)
{
if(IS_ROOT(MKPCHARP_STR(Pike_sp[e-args].u.string)))
{
root=e;
break;
}
}
#endif
while(root<args)
{
APPEND_PATH(&ret,
MKPCHARP_STR(Pike_sp[root-args].u.string),
Pike_sp[root-args].u.string->len);
root++;
}
UNSET_ONERROR(tmp);
pop_n_elems(args);
push_string(finish_string_builder(&ret));
}
#undef UNIX_COMBINE_PATH
#undef NT_COMBINE_PATH
|