# include "jam.h"
# include "filesys.h"
# if defined( unix ) || defined( NT ) || defined( __OS2__ )
# ifdef unix
# define DELIM '/'
# else
# define DELIM '\\'
# endif
void
file_parse( file, f )
char *file;
FILENAME *f;
{
#ifdef APPLE_EXTENSIONS
char * file_base = file;
#endif
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;
}
p = strrchr( file, '/' );
# ifndef unix
{
char *p1 = strrchr( file, '\\' );
p = p1 > p ? p1 : p;
}
# endif
if( p )
{
f->f_dir.ptr = file;
f->f_dir.len = p - file;
if( !f->f_dir.len )
f->f_dir.len = 1;
# ifndef unix
if( f->f_dir.len == 2 && file[1] == ':' )
f->f_dir.len = 3;
# endif
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 )) != NULL )
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;
}
#ifdef APPLE_EXTENSIONS
if ( DEBUG_VARSET ) {
fprintf(stderr, "[parsed %.*s as (G:%.*s R:%.*s D:%.*s B:%.*s A:%.*s S:%.*s M:%.*s)]\n", (file-file_base), file_base, f->f_grist.len, f->f_grist.ptr, 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_archive.len, f->f_archive.ptr, f->f_suffix.len, f->f_suffix.ptr, f->f_member.len, f->f_member.ptr);
}
#endif
}
#ifdef APPLE_EXTENSIONS
static unsigned append_quoted_characters (char * buffer, const char * characters, unsigned length, unsigned quoting_style, unsigned * needs_quoting_ptr)
{
if (quoting_style == NO_QUOTING) {
memcpy(buffer, characters, length);
if (needs_quoting_ptr != NULL) *needs_quoting_ptr = 0;
return length;
}
else {
register char * bufp = buffer;
unsigned needs_quoting = 0;
unsigned i;
if (quoting_style == SINGLE_QUOTING) {
for (i = 0; i < length; i++) {
register char ch = characters[i];
if (ch == '\'') {
*bufp++ = '\'';
*bufp++ = '\\';
*bufp++ = '\'';
*bufp++ = '\'';
needs_quoting = 1;
}
else if (!isalnum(ch) && ch != '_' && ch != '+' && ch != '-' && ch != '.' && ch != '/' && ch != ',' && ch != '~') {
*bufp++ = ch;
needs_quoting = 1;
}
else {
*bufp++ = ch;
}
}
}
else if (quoting_style == DOUBLE_QUOTING) {
for (i = 0; i < length; i++) {
register char ch = characters[i];
if (ch == '$' || ch == '`' || ch == '\"' || ch == '\\') {
*bufp++ = '\\';
needs_quoting = 1;
}
else if (!isalnum(ch) && ch != '_' && ch != '+' && ch != '-' && ch != '.' && ch != '/' && ch != ',' && ch != '~') {
needs_quoting = 1;
}
*bufp++ = ch;
}
}
else if (quoting_style == BACKSLASH_QUOTING) {
for (i = 0; i < length; i++) {
register char ch = characters[i];
if (!isalnum(ch) && ch != '_' && ch != '+' && ch != '-' && ch != '.' && ch != '/' && ch != ',' && ch != '~') {
*bufp++ = '\\';
needs_quoting = 1;
}
*bufp++ = ch;
}
}
else {
memcpy(bufp, characters, length);
bufp += length;
}
if (needs_quoting_ptr != NULL) *needs_quoting_ptr = needs_quoting;
return (bufp - buffer);
}
}
#endif
void
file_build( f, file, binding )
FILENAME *f;
char *file;
int binding;
{
#ifdef APPLE_EXTENSIONS
char * file_base = file;
unsigned any_substring_needs_quotes = 0;
unsigned this_substring_needs_quotes = 0;
#endif
if( f->f_grist.len )
{
if( f->f_grist.ptr[0] != '<' ) *file++ = '<';
#ifdef APPLE_EXTENSIONS
file += append_quoted_characters(file, f->f_grist.ptr, f->f_grist.len, f->quoting_style, &this_substring_needs_quotes);
any_substring_needs_quotes |= this_substring_needs_quotes;
#else
memcpy( file, f->f_grist.ptr, f->f_grist.len );
file += f->f_grist.len;
#endif
if( file[-1] != '>' ) *file++ = '>';
}
# ifdef unix
if( f->f_root.len
&& !( f->f_root.len == 1 && f->f_root.ptr[0] == '.' )
&& !( f->f_dir.len && f->f_dir.ptr[0] == '/' ) )
# else
if( f->f_root.len
&& !( f->f_root.len == 1 && f->f_root.ptr[0] == '.' )
&& !( f->f_dir.len && f->f_dir.ptr[0] == '/' )
&& !( f->f_dir.len && f->f_dir.ptr[0] == '\\' )
&& !( f->f_dir.len && f->f_dir.ptr[1] == ':' ) )
# endif
{
#ifdef APPLE_EXTENSIONS
file += append_quoted_characters(file, f->f_root.ptr, f->f_root.len, f->quoting_style, &this_substring_needs_quotes);
any_substring_needs_quotes |= this_substring_needs_quotes;
#else
memcpy( file, f->f_root.ptr, f->f_root.len );
file += f->f_root.len;
#endif
*file++ = DELIM;
}
if( f->f_dir.len )
{
#ifdef APPLE_EXTENSIONS
file += append_quoted_characters(file, f->f_dir.ptr, f->f_dir.len, f->quoting_style, &this_substring_needs_quotes);
any_substring_needs_quotes |= this_substring_needs_quotes;
#else
memcpy( file, f->f_dir.ptr, f->f_dir.len );
file += f->f_dir.len;
#endif
}
if( f->f_dir.len && ( f->f_base.len || f->f_suffix.len ) )
{
# ifndef UNIX
if( !( f->f_dir.len == 3 && f->f_dir.ptr[1] == ':' ) )
# endif
if( !( f->f_dir.len == 1 && f->f_dir.ptr[0] == DELIM ) )
*file++ = DELIM;
}
if( f->f_base.len && !f->f_archive.len )
{
#ifdef APPLE_EXTENSIONS
file += append_quoted_characters(file, f->f_base.ptr, f->f_base.len, f->quoting_style, &this_substring_needs_quotes);
any_substring_needs_quotes |= this_substring_needs_quotes;
#else
memcpy( file, f->f_base.ptr, f->f_base.len );
file += f->f_base.len;
#endif
}
if( !f->f_base.len && f->f_archive.len )
{
#ifdef APPLE_EXTENSIONS
file += append_quoted_characters(file, f->f_archive.ptr, f->f_archive.len, f->quoting_style, &this_substring_needs_quotes);
any_substring_needs_quotes |= this_substring_needs_quotes;
#else
memcpy( file, f->f_archive.ptr, f->f_archive.len );
file += f->f_archive.len;
#endif
}
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;
}
#ifdef APPLE_EXTENSIONS
file += append_quoted_characters(file, f->f_archive.ptr, f->f_archive.len, f->quoting_style, &this_substring_needs_quotes);
any_substring_needs_quotes |= this_substring_needs_quotes;
#else
memcpy( file, f->f_archive.ptr, f->f_archive.len );
file += f->f_archive.len;
#endif
}
if( f->f_suffix.len )
{
#ifdef APPLE_EXTENSIONS
file += append_quoted_characters(file, f->f_suffix.ptr, f->f_suffix.len, f->quoting_style, &this_substring_needs_quotes);
any_substring_needs_quotes |= this_substring_needs_quotes;
#else
memcpy( file, f->f_suffix.ptr, f->f_suffix.len );
file += f->f_suffix.len;
#endif
}
if( f->f_member.len )
{
*file++ = '(';
#ifdef APPLE_EXTENSIONS
file += append_quoted_characters(file, f->f_member.ptr, f->f_member.len, f->quoting_style, &this_substring_needs_quotes);
any_substring_needs_quotes |= this_substring_needs_quotes;
#else
memcpy( file, f->f_member.ptr, f->f_member.len );
file += f->f_member.len;
#endif
*file++ = ')';
}
#ifdef APPLE_EXTENSIONS
if (any_substring_needs_quotes && (f->quoting_style == DOUBLE_QUOTING || f->quoting_style == SINGLE_QUOTING)) {
memmove(file_base+1, file_base, (file++ - file_base));
file_base[0] = (f->quoting_style == DOUBLE_QUOTING) ? '\"' : '\'';
*file++ = (f->quoting_style == DOUBLE_QUOTING) ? '\"' : '\'';
}
if ( DEBUG_VARSET ) {
fprintf(stderr, "[quoted (G:%.*s R:%.*s D:%.*s B:%.*s A:%.*s S:%.*s M:%.*s)%s as %.*s]\n", f->f_grist.len, f->f_grist.ptr, 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_archive.len, f->f_archive.ptr, f->f_suffix.len, f->f_suffix.ptr, f->f_member.len, f->f_member.ptr, (f->quoting_style == DOUBLE_QUOTING ? ":Q" : (f->quoting_style == SINGLE_QUOTING ? ":q" : (f->quoting_style == BACKSLASH_QUOTING ? ":E" : ""))), (file-file_base), file_base);
}
#endif
*file = 0;
}
void
file_parent( f )
FILENAME *f;
{
f->f_base.ptr =
f->f_suffix.ptr =
f->f_member.ptr =
f->f_archive.ptr = "";
f->f_base.len =
f->f_suffix.len =
f->f_member.len =
f->f_archive.len = 0;
}
# endif