# ifdef VMS
# define DEBUG
# include "jam.h"
# include "filesys.h"
void
file_parse( file, f )
char *file;
FILENAME *f;
{
char *p, *q;
char *end;
memset( (char *)f, 0, sizeof( *f ) );
if( file[0] == '<' && ( p = strchr( file, '>' ) ) )
{
f->f_grist.ptr = file;
f->f_grist.len = p - file;
file = p + 1;
}
if( ( p = strchr( file, ']' ) ) || ( p = strchr( file, ':' ) ) )
{
f->f_dir.ptr = file;
f->f_dir.len = p + 1 - file;
file = p + 1;
}
end = file + strlen( file );
if( ( p = strchr( file, '(' ) ) && end[-1] == ')' )
{
f->f_member.ptr = p + 1;
f->f_member.len = end - p - 2;
end = p;
}
p = 0;
q = file;
while( q = memchr( q, '.', end - q ) )
p = q++;
if( p )
{
f->f_suffix.ptr = p;
f->f_suffix.len = end - p;
end = p;
}
f->f_base.ptr = file;
f->f_base.len = end - file;
if (strncmp (file, "lib", 3) == 0) {
f->f_archive.ptr = file+3;
f->f_archive.len = end - file - 3;
} else {
f->f_archive.ptr = file;
f->f_archive.len = end - file;
}
f->parent = 0;
}
# define DIR_EMPTY 0
# define DIR_DEV 1
# define DIR_DEVDIR 2
# define DIR_DOTDIR 3
# define DIR_DASHDIR 4
# define DIR_ABSDIR 5
# define DIR_ROOT 6
# define G_DIR 0
# define G_ROOT 1
# define G_VAD 2
# define G_DRD 3
# define G_VRD 4
# define G_DDD 5
static int grid[7][7] = {
G_DIR, G_DIR, G_DIR, G_DIR, G_DIR, G_DIR, G_DIR,
G_ROOT, G_DIR, G_DIR, G_VRD, G_VAD, G_VAD, G_VAD,
G_ROOT, G_DIR, G_DIR, G_DRD, G_VAD, G_VAD, G_VAD,
G_ROOT, G_DIR, G_DIR, G_DRD, G_DIR, G_DIR, G_DIR,
G_ROOT, G_DIR, G_DIR, G_DRD, G_DDD, G_DIR, G_DIR,
G_ROOT, G_DIR, G_DIR, G_DRD, G_DIR, G_DIR, G_DIR,
G_ROOT, G_DIR, G_DIR, G_VRD, G_DIR, G_DIR, G_DIR,
} ;
struct dirinf {
int flags;
struct {
char *ptr;
int len;
} dev, dir;
} ;
static char *
strnchr( buf, c, len )
char *buf;
int c;
int len;
{
while( len-- )
if( *buf && *buf++ == c )
return buf - 1;
return 0;
}
static void
dir_flags( buf, len, i )
char *buf;
int len;
struct dirinf *i;
{
char *p;
if( !buf || !len )
{
i->flags = DIR_EMPTY;
i->dev.ptr =
i->dir.ptr = 0;
i->dev.len =
i->dir.len = 0;
}
else if( p = strnchr( buf, ':', len ) )
{
i->dev.ptr = buf;
i->dev.len = p + 1 - buf;
i->dir.ptr = buf + i->dev.len;
i->dir.len = len - i->dev.len;
i->flags = i->dir.len && *i->dir.ptr == '[' ? DIR_DEVDIR : DIR_DEV;
}
else
{
i->dev.ptr = buf;
i->dev.len = 0;
i->dir.ptr = buf;
i->dir.len = len;
if( *buf == '[' && buf[1] == ']' )
i->flags = DIR_EMPTY;
else if( *buf == '[' && buf[1] == '.' )
i->flags = DIR_DOTDIR;
else if( *buf == '[' && buf[1] == '-' )
i->flags = DIR_DASHDIR;
else
i->flags = DIR_ABSDIR;
}
if( i->dir.len == 8 && !strncmp( i->dir.ptr, "[000000]", 8 ) )
i->flags = DIR_ROOT;
}
void
file_build( f, file, binding )
FILENAME *f;
char *file;
int binding;
{
char *ofile = file;
struct dirinf root, dir;
int g;
if( f->f_grist.len )
{
if( f->f_grist.ptr[0] != '<' ) *file++ = '<';
memcpy( file, f->f_grist.ptr, f->f_grist.len );
file += f->f_grist.len;
if( file[-1] != '>' ) *file++ = '>';
}
dir_flags( f->f_root.ptr, f->f_root.len, &root );
dir_flags( f->f_dir.ptr, f->f_dir.len, &dir );
switch( g = grid[ root.flags ][ dir.flags ] )
{
case G_DIR:
memcpy( file, f->f_dir.ptr, f->f_dir.len );
file += f->f_dir.len;
break;
case G_ROOT:
memcpy( file, f->f_root.ptr, f->f_root.len );
file += f->f_root.len;
break;
case G_VAD:
memcpy( file, root.dev.ptr, root.dev.len );
file += root.dev.len;
memcpy( file, dir.dir.ptr, dir.dir.len );
file += dir.dir.len;
break;
case G_DRD:
case G_DDD:
memcpy( file, f->f_root.ptr, f->f_root.len );
file += f->f_root.len;
if( file[-1] == ']' )
--file;
if( g == G_DDD )
*file++ = '.';
memcpy( file, dir.dir.ptr + 1, dir.dir.len - 1 );
file += dir.dir.len - 1;
break;
case G_VRD:
memcpy( file, root.dev.ptr, root.dev.len );
file += root.dev.len;
*file++ = '[';
memcpy( file, dir.dir.ptr + 2, dir.dir.len - 2 );
file += dir.dir.len - 2;
break;
}
# ifdef DEBUG
if( DEBUG_SEARCH && ( root.flags || dir.flags ) )
{
*file = 0;
printf( "%d x %d = %d (%s)\n", root.flags, dir.flags,
grid[ root.flags ][ dir.flags ], ofile );
}
# endif
if( file[-1] == ']' && f->parent )
{
while( file-- > ofile )
{
if( *file == '.' )
{
*file++ = ']';
break;
}
else if( *file == '-' )
{
if( file > ofile && file[-1] == '.' )
--file;
*file++ = ']';
break;
}
else if( *file == '[' )
{
if( file[1] == ']' )
{
file += 2;
}
else
{
strcpy( file, "[000000]" );
file += 8;
}
break;
}
}
}
if( f->f_base.len && !f->f_archive.len )
{
memcpy( file, f->f_base.ptr, f->f_base.len );
file += f->f_base.len;
}
if( !f->f_base.len && f->f_archive.len )
{
memcpy( file, f->f_archive.ptr, f->f_archive.len );
file += f->f_archive.len;
}
if( f->f_base.len && f->f_archive.len )
{
if( strncmp (f->f_base.ptr, "lib", 3) == 0 )
{
memcpy( file, f->f_base.ptr, 3 );
file += 3;
}
memcpy( file, f->f_archive.ptr, f->f_archive.len );
file += f->f_archive.len;
}
if( f->f_suffix.len )
{
memcpy( file, f->f_suffix.ptr, f->f_suffix.len );
file += f->f_suffix.len;
}
else if( binding && f->f_base.len )
{
*file++ = '.';
}
if( f->f_member.len )
{
*file++ = '(';
memcpy( file, f->f_member.ptr, f->f_member.len );
file += f->f_member.len;
*file++ = ')';
}
*file = 0;
# ifdef DEBUG
if( DEBUG_SEARCH )
printf("built %.*s + %.*s / %.*s suf %.*s mem %.*s -> %s\n",
f->f_root.len, f->f_root.ptr,
f->f_dir.len, f->f_dir.ptr,
f->f_base.len, f->f_base.ptr,
f->f_suffix.len, f->f_suffix.ptr,
f->f_member.len, f->f_member.ptr,
ofile );
# endif
}
void
file_parent( f )
FILENAME *f;
{
if( f->f_base.len )
{
f->f_base.ptr =
f->f_suffix.ptr =
f->f_member.ptr = "";
f->f_base.len =
f->f_suffix.len =
f->f_member.len = 0;
}
else
{
f->parent = 1;
}
}
# endif