⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pathvms.c

📁 Boost provides free peer-reviewed portable C++ source libraries. We emphasize libraries that work
💻 C
字号:
/* * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. * * This file is part of Jam - see jam.c for Copyright information. *//*  This file is ALSO: *  Copyright 2001-2004 David Abrahams. *  Distributed under the Boost Software License, Version 1.0. *  (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) */# include "jam.h"# include "pathsys.h"# ifdef OS_VMS# define DEBUG/* * pathvms.c - manipulate file names on VMS * * External routines: * *	path_parse() - split a file name into dir/base/suffix/member *	path_build() - build a filename given dir/base/suffix/member *	path_parent() - make a PATHNAME point to its parent dir * * File_parse() and path_build() just manipuate a string and a structure; * they do not make system calls. * * WARNING!  This file contains voodoo logic, as black magic is  * necessary for wrangling with VMS file name.  Woe be to people * who mess with this code. * * 02/09/95 (seiwald) - bungled R=[xxx] - was using directory length! * 05/03/96 (seiwald) - split from filevms.c *//* * path_parse() - split a file name into dir/base/suffix/member */voidpath_parse( 	char	*file,	PATHNAME *f ){	char *p, *q;	char *end;		memset( (char *)f, 0, sizeof( *f ) );	/* Look for <grist> */	if( file[0] == '<' && ( p = strchr( file, '>' ) ) )	{	    f->f_grist.ptr = file;	    f->f_grist.len = p - file;	    file = p + 1;	}	/* Look for dev:[dir] or dev: */	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 );	/* Look for (member) */	if( ( p = strchr( file, '(' ) ) && end[-1] == ')' )	{	    f->f_member.ptr = p + 1;	    f->f_member.len = end - p - 2;	    end = p;	} 	/* Look for .suffix */	/* This would be memrchr() */	p = 0;	q = file;	while( q = (char *)memchr( q, '.', end - q ) )	    p = q++;	if( p )	{	    f->f_suffix.ptr = p;	    f->f_suffix.len = end - p;	    end = p;	}	/* Leaves base */	f->f_base.ptr = file;	f->f_base.len = end - file;	/* Is this a directory without a file spec? */	f->parent = 0;}/* *	dir		mods		result *	---		---		------ * Rerooting: * *	(none)		:R=dev:		dev:		 *	devd:		:R=dev:		devd: *	devd:[dir]	:R=dev:		devd:[dir] *	[.dir]		:R=dev:		dev:[dir]	questionable *	[dir]		:R=dev:		dev:[dir] * *	(none)		:R=[rdir]	[rdir]		questionable *	devd:		:R=[rdir]	devd: *	devd:[dir]	:R=[rdir]	devd:[dir] *	[.dir]		:R=[rdir]	[rdir.dir]	questionable *	[dir]		:R=[rdir]	[rdir] * *	(none)		:R=dev:[root]	dev:[root] *	devd:		:R=dev:[root]	devd: *	devd:[dir]	:R=dev:[root]	devd:[dir] *	[.dir]		:R=dev:[root]	dev:[root.dir] *	[dir]		:R=dev:[root]	[dir] * * Climbing to parent: * */# define DIR_EMPTY	0	/* empty string */# define DIR_DEV	1	/* dev: */# define DIR_DEVDIR	2	/* dev:[dir] */# define DIR_DOTDIR	3	/* [.dir] */# define DIR_DASHDIR	4	/* [-] or [-.dir] */# define DIR_ABSDIR	5	/* [dir] */# define DIR_ROOT	6	/* [000000] or dev:[000000] */# define G_DIR		0	/* take just dir */# define G_ROOT		1	/* take just root */# define G_VAD		2	/* root's dev: + [abs] */# define G_DRD		3	/* root's dev:[dir] + [.rel] */# define G_VRD		4	/* root's dev: + [.rel] made [abs] */# define G_DDD		5	/* root's dev:[dir] + . + [dir] */static int grid[7][7] = {/* root/dir	EMPTY	DEV	DEVDIR	DOTDIR	DASH,	ABSDIR	ROOT *//* EMPTY */	G_DIR,	G_DIR,	G_DIR,	G_DIR,	G_DIR,	G_DIR,	G_DIR,/* DEV */	G_ROOT,	G_DIR,	G_DIR,	G_VRD,	G_VAD,	G_VAD,	G_VAD,/* DEVDIR */	G_ROOT,	G_DIR,	G_DIR,	G_DRD,	G_VAD,	G_VAD,	G_VAD,/* DOTDIR */	G_ROOT,	G_DIR,	G_DIR,	G_DRD,	G_DIR,	G_DIR,	G_DIR,/* DASHDIR */	G_ROOT,	G_DIR,	G_DIR,	G_DRD,	G_DDD,	G_DIR,	G_DIR,/* ABSDIR */	G_ROOT,	G_DIR,	G_DIR,	G_DRD,	G_DIR,	G_DIR,	G_DIR,/* ROOT */	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( 	char	*buf,	int	c,	int	len ){	while( len-- )	    if( *buf && *buf++ == c )		return buf - 1;	return 0;}static voiddir_flags( 	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;	}	/* But if its rooted in any way */	if( i->dir.len == 8 && !strncmp( i->dir.ptr, "[000000]", 8 ) )	    i->flags = DIR_ROOT;}/* * path_build() - build a filename given dir/base/suffix/member */voidpath_build(	PATHNAME *f,	string	*file,	int	binding ){    struct dirinf root, dir;    int g;    file_build1( f, file );            /* Get info on root and dir for combining. */    dir_flags( f->f_root.ptr, f->f_root.len, &root );    dir_flags( f->f_dir.ptr, f->f_dir.len, &dir );    /* Combine */    switch( g = grid[ root.flags ][ dir.flags ] )    {    case G_DIR:	        /* take dir */        string_append_range( file, f->f_dir.ptr, f->f_dir.ptr + f->f_dir.len  );        break;    case G_ROOT:	        /* take root */        string_append_range( file, f->f_root.ptr, f->f_root.ptr + f->f_root.len  );        break;    case G_VAD:	        /* root's dev + abs directory */        string_append_range( file, root.dev.ptr, root.dev.ptr + root.dev.len  );        string_append_range( file, dir.dir.ptr, dir.dir.ptr + dir.dir.len  );        break;		    case G_DRD:	    case G_DDD:        /* root's dev:[dir] + rel directory */        string_append_range( file, f->f_root.ptr, f->f_root.ptr + f->f_root.len  );        /* sanity checks: root ends with ] */        if( file->value[file->size - 1] == ']' )            string_pop_back( file );        /* Add . if separating two -'s */        if( g == G_DDD )            string_push_back( file, '.' );        /* skip [ of dir */        string_append_range( file, dir.dir.ptr + 1, dir.dir.ptr + 1 + dir.dir.len - 1  );        break;    case G_VRD:	        /* root's dev + rel directory made abs */        string_append_range( file, root.dev.ptr, root.dev.ptr + root.dev.len  );        string_push_back( file, '[' );        /* skip [. of rel dir */        string_append_range( file, dir.dir.ptr + 2, dir.dir.ptr + 2 + dir.dir.len - 2  );        break;    }# ifdef DEBUG    if( DEBUG_SEARCH && ( root.flags || dir.flags ) )    {        printf( "%d x %d = %d (%s)\n", root.flags, dir.flags,                grid[ root.flags ][ dir.flags ], file->value );    }# endif     /*      * Now do the special :P modifier when no file was present.     *	(none)		(none)     *	[dir1.dir2]	[dir1]     *	[dir]		[000000]     *	[.dir]		(none)     *	[]		[]     */    if( file->value[file->size - 1] == ']' && f->parent )    {        char* p = file->value + file->size;        while( p-- > file->value )        {            if( *p == '.' )            {                /* If we've truncated everything and left with '[',                   return empty string. */                if (p == file->value + 1)                    string_truncate( file, 0 );                else {                    string_truncate( file, p - file->value );                    string_push_back( file, ']' );                }                break;            }            else if( *p == '-' )            {                /* handle .- or - */                if( p > file->value && p[-1] == '.' )                    --p;                                *p++ = ']';                break;            }            else if( *p == '[' )            {                if( p[1] == ']' )                {                    /* CONSIDER: I don't see any use of this code. We immediately                       break, and 'p' is a local variable. */                    p += 2;                }                else                {                    string_truncate( file, p - file->value );                    string_append( file, "[000000]" );                }                break;            }        }    }    /* Now copy the file pieces. */    if( f->f_base.len )    {        string_append_range( file, f->f_base.ptr, f->f_base.ptr + f->f_base.len  );    }    /* If there is no suffix, we append a "." onto all generated */    /* names.  This keeps VMS from appending its own (wrong) idea */    /* of what the suffix should be. */    if( f->f_suffix.len )    {        string_append_range( file, f->f_suffix.ptr, f->f_suffix.ptr + f->f_suffix.len  );    }    else if( binding && f->f_base.len )    {        string_push_back( file, '.' );    }    if( f->f_member.len )    {        string_push_back( file, '(' );        string_append_range( file, f->f_member.ptr, f->f_member.ptr + f->f_member.len  );        string_push_back( file, ')' );    }# 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,               file->value );# endif}/* *	path_parent() - make a PATHNAME point to its parent dir */voidpath_parent( PATHNAME *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 /* VMS */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -