/* * Copyright 1995, 1996 Perforce Software. All rights reserved. * * This file is part of Perforce - the FAST SCM System. */ /* * PathMac - pathname manipuation for Mac. * * Mac file syntax, for the dumb: * * vol:dir1:dir2:file * * If it's: * * f -> vol:dir1:dir2:file * :dir3:f -> vol:dir1:dir2:dir3:f * ::f -> vol:dir1:f * :::f -> vol:f * ::::f -> vol:f * * Directories should end with :, but that is not required. * * Files should not begin with .'s or have :'s in them. */ # include <stdhdrs.h> # include <ctype.h> # include <error.h> # include <strbuf.h> # include <pathsys.h> # include <pathmac.h> /* * IsUnder( path, root ) - is 'path under 'root'? */ static int IsUnder( StrRef *path, const char *root ) { char *s = path->Text(); // Make sure initial string matches // s=foo:bar:ola root=foo:bar -> s=ola // s=foo:bar:ola root=foo:bar: -> s=:ola while( *s && ( tolower( *s ) == tolower( *root ) ) ) ++s, ++root; // Make sure we ended at the end of root, and at a : in path. if( *root || root[-1] != ':' && *s && *s++ != ':' ) return 0; // Reset path to exclude initial 'root' substring. path->Set( s, path->Text() + path->Length() - s ); return 1; } int PathMAC::IsUnderRoot( const StrPtr &root ) { StrRef pathTmp( *this ); return IsUnder( &pathTmp, root.Text() ); } void PathMAC::SetLocal( const StrPtr &root, const StrPtr &local ) { // (local) root + (local) local -> absolute local path // local may be relative. if( local[0] != ':' && strchr( local.Text(), ':' ) ) { // Absolute path - foo:bar but not :foo:bar Set( local ); } else { // Relative path - :foo:bar, ::foo:bar, or just bar // Start with root; allow SetLocal( this, ... ) if( this != &root ) Set( root ); StrRef l( local ); // Leading : indicated relative path; skip it if( l[0] == ':' ) l += 1; // Each leading : left in path means up a directory in root. while( IsUnder( &l, ":" ) ) ToParent(); // Ensure local (if any) is separated from root with :. if( !Length() || ( Text()[ Length() - 1 ] != ':' ) && l.Length() ) Append( ":", 1 ); // Finally, append what's left of local. Append( &l ); } } void PathMAC::SetCanon( const StrPtr &root, const StrPtr &canon ) { // (local) root + (canon) canon -> absolute local path // canon cannot be relative. // Start with root Set( root ); // Separate with : (if root didn't end in one) if( !Length() || Text()[ Length() - 1 ] != ':' ) Append( ":", 1 ); // Remember starting point of canon int len = Length(); // Append canon and canon / with MAC's : Append( &canon ); for( ; len < Length(); ++len ) { if( Text()[len] == '/' ) Text()[len] = ':'; } } int PathMAC::GetCanon( const StrPtr &root, StrBuf &target ) { // (local) this - (local) root = (canon) target // this and root are absolute paths. // We start with our local syntax path StrRef here; here.Set( this ); // We strip off the root, leaving the relative path. if( !IsUnder( &here, root.Text() ) ) return 0; // If there is no relative path left, leave target as is. if( !here.Length() ) return 1; // Separate 'this' from target with / // We shouldn't need this check, but if someone enters // a rel path beginning with a /, we don't want two if( here.Text()[0] != '/' ) target.Append( "/", 1 ); // Target gets appended with canonical relative path // Replace MAC's : with canon / int len = target.Length(); target.Append( &here ); for( ; len < target.Length(); ++len ) { if( target.Text()[len] == ':' ) target.Text()[len] = '/'; } return 1; } int PathMAC::ToParent( StrBuf *file ) { char *start = Text(); char *end = start + Length(); char *oldEnd = end; // strip off trialing : // find preceeding : // Save file // strip preceeding : if( end > start && end[-1] == ':' ) --end; while( end > start && end[-1] != ':' ) --end; if( file ) file->Set( end, oldEnd - end ); if( end > start && end[-1] == ':' ) --end; // If there was no :, we can't go to the parent. if( end == oldEnd || end == start ) return 0; SetEnd( end ); Terminate(); return 1; }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#1 | 14945 | Newtopian |
Merging //guest/perforce_software/p4/... to //guest/Newtopian/p4/... |
||
//guest/perforce_software/p4/2014.1/sys/pathmac.cc | |||||
#1 | 12188 | Matt Attaway | Move 'main' p4 into a release specific directory in prep for new releases | ||
//guest/perforce_software/p4/sys/pathmac.cc | |||||
#1 | 9129 | Matt Attaway | Initial commit of the 2014.1 p4/p4api source code |