Remove cvscopy and related tools

This commit is contained in:
rdb 2019-01-11 23:32:37 +01:00
parent 7464e18b72
commit 1895abff66
16 changed files with 2 additions and 2599 deletions

View File

@ -1,44 +0,0 @@
.\" Automatically generated by fltcopy -write-bam
.TH FLTCOPY 1 "27 December 2014" "1.9.0" Panda3D
.SH NAME
fltcopy \- copy MultiGen .flt files into a CVS source hierarchy
.SH SYNOPSIS
\fBfltcopy\fR [opts] file.flt [file.flt ... ]
.SH DESCRIPTION
fltcopy copies one or more MultiGen .flt files into a CVS source hierarchy. Rather than copying the named files immediately into the current directory, it first scans the entire source hierarchy, identifying all the already\-existing files. If the named file to copy matches the name of an already\-existing file in the current directory or elsewhere in the hierarchy, that file is overwritten. Other .flt files, as well as texture files, that are externally referenced by the named .flt file(s) are similarly copied.
.SH OPTIONS
.TP
.BI "\-pr " "path_replace"
Sometimes references to other files (textures, external references) are stored with a full path that is appropriate for some other system, but does not exist here. This option may be used to specify how those invalid paths map to correct paths. Generally, this is of the form 'orig_prefix=replacement_prefix', which indicates a particular initial sequence of characters that should be replaced with a new sequence; e.g. '/c/home/models=/beta/fish'. If the replacement prefix does not begin with a slash, the file will then be searched for along the search path specified by -pp. You may use standard filename matching characters ('*', '?', etc.) in the original prefix, and '**' as a component by itself stands for any number of components.
This option may be repeated as necessary; each file will be tried against each specified method, in the order in which they appear in the command line, until the file is found. If the file is not found, the last matching prefix is used anyway.
.TP
.BI "\-pp " "dirname"
Adds the indicated directory name to the list of directories to search for filenames referenced by the source file. This is used only for relative paths, or for paths that are made relative by a -pr replacement string that doesn't begin with a leading slash. The model-path is always implicitly searched anyway.
.TP
.B \-f
Force the copy to happen without any input from the user. If a file with the same name exists anywhere in the source hierarchy, it will be overwritten without prompting; if a file does not yet exist, it will be created in the directory named by -d or by -m, as appropriate.
.TP
.B \-i
The opposite of -f, this will prompt the user before each action. The default is only to prompt the user when an action is ambiguous or unusual.
.TP
.BI "\-d " "dirname"
Copy model files that are not already present somewhere in the tree to the indicated directory. The default is the current directory.
.TP
.BI "\-m " "dirname"
Copy texture map files to the indicated directory. The default is src/maps from the root directory.
.TP
.BI "\-root " "dirname"
Specify the root of the CVS source hierarchy. The default is to use the ppremake convention of locating the directory above the -d directory that contains a file called Package.pp.
.TP
.BI "\-key " "filename"
Specify the name of the file that must exist in each directory for it to be considered part of the CVS source hierarchy. The default is the ppremake convention, "Sources.pp". Other likely candidates are "CVS" to search a CVS hierarchy, or "." to include all subdirectories indiscriminately.
.TP
.B \-nc
Do not attempt to add newly-created files to CVS. The default is to add them.
.TP
.BI "\-cvs " "cvs_binary"
Specify how to run the cvs program for adding newly-created files. The default is simply "cvs".
.TP
.B \-h
Display this help page.

View File

@ -3361,7 +3361,6 @@ if (PkgSkip("PANDATOOL")==0):
CopyAllHeaders('pandatool/src/progbase')
CopyAllHeaders('pandatool/src/eggbase')
CopyAllHeaders('pandatool/src/bam')
CopyAllHeaders('pandatool/src/cvscopy')
CopyAllHeaders('pandatool/src/daeegg')
CopyAllHeaders('pandatool/src/daeprogs')
CopyAllHeaders('pandatool/src/dxf')
@ -5734,15 +5733,6 @@ if not PkgSkip("PANDATOOL"):
TargetAdd('egg2bam.exe', input=COMMON_EGG2X_LIBS)
TargetAdd('egg2bam.exe', opts=['ADVAPI', 'FFTW'])
#
# DIRECTORY: pandatool/src/cvscopy/
#
if not PkgSkip("PANDATOOL"):
OPTS=['DIR:pandatool/src/cvscopy']
TargetAdd('p3cvscopy_composite1.obj', opts=OPTS, input='p3cvscopy_composite1.cxx')
TargetAdd('libp3cvscopy.lib', input='p3cvscopy_composite1.obj')
#
# DIRECTORY: pandatool/src/daeegg/
#
@ -6007,7 +5997,7 @@ if not PkgSkip("PANDATOOL") and not PkgSkip("EGG"):
#
if not PkgSkip("PANDATOOL"):
OPTS=['DIR:pandatool/src/fltprogs', 'DIR:pandatool/src/flt', 'DIR:pandatool/src/cvscopy']
OPTS=['DIR:pandatool/src/fltprogs', 'DIR:pandatool/src/flt']
TargetAdd('flt-info_fltInfo.obj', opts=OPTS, input='fltInfo.cxx')
TargetAdd('flt-info.exe', input='flt-info_fltInfo.obj')
TargetAdd('flt-info.exe', input='libp3flt.lib')
@ -6024,15 +6014,6 @@ if not PkgSkip("PANDATOOL"):
TargetAdd('flt-trans.exe', input=COMMON_PANDA_LIBS)
TargetAdd('flt-trans.exe', opts=['ADVAPI'])
TargetAdd('fltcopy_fltCopy.obj', opts=OPTS, input='fltCopy.cxx')
TargetAdd('fltcopy.exe', input='fltcopy_fltCopy.obj')
TargetAdd('fltcopy.exe', input='libp3cvscopy.lib')
TargetAdd('fltcopy.exe', input='libp3flt.lib')
TargetAdd('fltcopy.exe', input='libp3progbase.lib')
TargetAdd('fltcopy.exe', input='libp3pandatoolbase.lib')
TargetAdd('fltcopy.exe', input=COMMON_PANDA_LIBS)
TargetAdd('fltcopy.exe', opts=['ADVAPI'])
if not PkgSkip("EGG"):
TargetAdd('egg2flt_eggToFlt.obj', opts=OPTS, input='eggToFlt.cxx')
TargetAdd('egg2flt.exe', input='egg2flt_eggToFlt.obj')
@ -6421,7 +6402,7 @@ for VER in MAYAVERSIONS:
# No x86_64 support.
continue
OPTS=['DIR:pandatool/src/mayaprogs', 'DIR:pandatool/src/maya', 'DIR:pandatool/src/mayaegg', 'DIR:pandatool/src/cvscopy', 'BUILDING:MISC', VER]
OPTS=['DIR:pandatool/src/mayaprogs', 'DIR:pandatool/src/maya', 'DIR:pandatool/src/mayaegg', 'BUILDING:MISC', VER]
TargetAdd('mayaeggimport'+VNUM+'_mayaeggimport.obj', opts=OPTS, input='mayaEggImport.cxx')
TargetAdd('mayaeggimport'+VNUM+'.mll', input='mayaegg'+VNUM+'_loader.obj')
TargetAdd('mayaeggimport'+VNUM+'.mll', input='mayaeggimport'+VNUM+'_mayaeggimport.obj')
@ -6486,16 +6467,6 @@ for VER in MAYAVERSIONS:
TargetAdd('egg2maya'+VNUM+'_bin.exe', input=COMMON_EGG2X_LIBS)
TargetAdd('egg2maya'+VNUM+'_bin.exe', opts=['ADVAPI', VER])
TargetAdd('mayacopy'+VNUM+'_mayaCopy.obj', opts=OPTS, input='mayaCopy.cxx')
TargetAdd('mayacopy'+VNUM+'_bin.exe', input='mayacopy'+VNUM+'_mayaCopy.obj')
TargetAdd('mayacopy'+VNUM+'_bin.exe', input='libp3cvscopy.lib')
TargetAdd('mayacopy'+VNUM+'_bin.exe', input='libmaya'+VNUM+'.lib')
if GetTarget() == 'windows':
TargetAdd('mayacopy'+VNUM+'_bin.exe', input=COMMON_EGG2X_LIBS)
else:
TargetAdd('mayacopy'+VNUM+'_bin.exe', input=COMMON_EGG2X_LIBS)
TargetAdd('mayacopy'+VNUM+'_bin.exe', opts=['ADVAPI', VER])
TargetAdd('mayasavepview'+VNUM+'_mayaSavePview.obj', opts=OPTS, input='mayaSavePview.cxx')
TargetAdd('libmayasavepview'+VNUM+'.mll', input='mayasavepview'+VNUM+'_mayaSavePview.obj')
TargetAdd('libmayasavepview'+VNUM+'.mll', opts=['ADVAPI', VER])
@ -6512,11 +6483,6 @@ for VER in MAYAVERSIONS:
TargetAdd('egg2maya'+VNUM+'.exe', input=COMMON_DTOOL_LIBS)
TargetAdd('egg2maya'+VNUM+'.exe', opts=['ADVAPI'])
TargetAdd('mayacopy'+VNUM+'.exe', input='mayapath'+VNUM+'.obj')
TargetAdd('mayacopy'+VNUM+'.exe', input='libpandaexpress.dll')
TargetAdd('mayacopy'+VNUM+'.exe', input=COMMON_DTOOL_LIBS)
TargetAdd('mayacopy'+VNUM+'.exe', opts=['ADVAPI'])
#
# DIRECTORY: contrib/src/ai/
#

View File

@ -4572,17 +4572,6 @@
<File RelativePath="..\pandatool\src\lwoprogs\lwoScan.h"></File>
<File RelativePath="..\pandatool\src\lwoprogs\lwoScan.cxx"></File>
</Filter>
<Filter Name="cvscopy">
<File RelativePath="..\pandatool\src\cvscopy\cvscopy_composite1.cxx"></File>
<File RelativePath="..\pandatool\src\cvscopy\testCopy.cxx"></File>
<File RelativePath="..\pandatool\src\cvscopy\cvsSourceDirectory.h"></File>
<File RelativePath="..\pandatool\src\cvscopy\testCopy.h"></File>
<File RelativePath="..\pandatool\src\cvscopy\cvsSourceDirectory.cxx"></File>
<File RelativePath="..\pandatool\src\cvscopy\cvsCopy.cxx"></File>
<File RelativePath="..\pandatool\src\cvscopy\cvsCopy.h"></File>
<File RelativePath="..\pandatool\src\cvscopy\cvsSourceTree.cxx"></File>
<File RelativePath="..\pandatool\src\cvscopy\cvsSourceTree.h"></File>
</Filter>
<Filter Name="pandatoolbase">
<File RelativePath="..\pandatool\src\pandatoolbase\animationConvert.cxx"></File>
<File RelativePath="..\pandatool\src\pandatoolbase\pathReplace.I"></File>
@ -4750,11 +4739,9 @@
<Filter Name="fltprogs">
<File RelativePath="..\pandatool\src\fltprogs\fltToEgg.cxx"></File>
<File RelativePath="..\pandatool\src\fltprogs\eggToFlt.cxx"></File>
<File RelativePath="..\pandatool\src\fltprogs\fltCopy.h"></File>
<File RelativePath="..\pandatool\src\fltprogs\fltTrans.h"></File>
<File RelativePath="..\pandatool\src\fltprogs\fltInfo.h"></File>
<File RelativePath="..\pandatool\src\fltprogs\fltInfo.cxx"></File>
<File RelativePath="..\pandatool\src\fltprogs\fltCopy.cxx"></File>
<File RelativePath="..\pandatool\src\fltprogs\fltTrans.cxx"></File>
<File RelativePath="..\pandatool\src\fltprogs\fltToEgg.h"></File>
<File RelativePath="..\pandatool\src\fltprogs\eggToFlt.h"></File>
@ -4920,11 +4907,9 @@
<File RelativePath="..\pandatool\src\mayaprogs\mayaToEgg_client.h"></File>
<File RelativePath="..\pandatool\src\mayaprogs\blend_test.cxx"></File>
<File RelativePath="..\pandatool\src\mayaprogs\mayaToEgg_server.h"></File>
<File RelativePath="..\pandatool\src\mayaprogs\mayaCopy.h"></File>
<File RelativePath="..\pandatool\src\mayaprogs\eggToMaya.h"></File>
<File RelativePath="..\pandatool\src\mayaprogs\mayaSavePview.h"></File>
<File RelativePath="..\pandatool\src\mayaprogs\mayaToEgg_server.cxx"></File>
<File RelativePath="..\pandatool\src\mayaprogs\mayaCopy.cxx"></File>
<File RelativePath="..\pandatool\src\mayaprogs\eggToMaya.cxx"></File>
<File RelativePath="..\pandatool\src\mayaprogs\normal_test.cxx"></File>
<File RelativePath="..\pandatool\src\mayaprogs\mayaSavePview.cxx"></File>

View File

@ -1,501 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cvsCopy.cxx
* @author drose
* @date 2000-10-31
*/
#include "cvsCopy.h"
#include "cvsSourceDirectory.h"
#include "pnotify.h"
#include <algorithm>
using std::string;
/**
*
*/
CVSCopy::
CVSCopy() {
_model_dirname = ".";
_key_filename = "Sources.pp";
_cvs_binary = "cvs";
_user_aborted = false;
_model_dir = nullptr;
_map_dir = nullptr;
clear_runlines();
add_runline("[opts] file [file ... ]");
add_option
("f", "", 80,
"Force the copy to happen without any input from the user. If a file "
"with the same name exists anywhere in the source hierarchy, it will "
"be overwritten without prompting; if a file does not yet exist, it "
"will be created in the directory named by -d or by -m, as appropriate.",
&CVSCopy::dispatch_none, &_force);
add_option
("i", "", 80,
"The opposite of -f, this will prompt the user before each action. "
"The default is only to prompt the user when an action is ambiguous "
"or unusual.",
&CVSCopy::dispatch_none, &_interactive);
add_option
("d", "dirname", 80,
"Copy model files that are not already present somewhere in the tree "
"to the indicated directory. The default is the current directory.",
&CVSCopy::dispatch_filename, &_got_model_dirname, &_model_dirname);
add_option
("m", "dirname", 80,
"Copy texture map files to the indicated directory. The default "
"is src/maps from the root directory.",
&CVSCopy::dispatch_filename, &_got_map_dirname, &_map_dirname);
add_option
("root", "dirname", 80,
"Specify the root of the CVS source hierarchy. The default is to "
"use the ppremake convention of locating the directory above the -d "
"directory that contains a file called Package.pp.",
&CVSCopy::dispatch_filename, &_got_root_dirname, &_root_dirname);
add_option
("key", "filename", 80,
"Specify the name of the file that must exist in each directory for "
"it to be considered part of the CVS source hierarchy. The default "
"is the ppremake convention, \"Sources.pp\". Other likely candidates "
"are \"CVS\" to search a CVS hierarchy, or \".\" to include "
"all subdirectories indiscriminately.",
&CVSCopy::dispatch_filename, nullptr, &_key_filename);
add_option
("nc", "", 80,
"Do not attempt to add newly-created files to CVS. The default "
"is to add them.",
&CVSCopy::dispatch_none, &_no_cvs);
add_option
("cvs", "cvs_binary", 80,
"Specify how to run the cvs program for adding newly-created files. "
"The default is simply \"cvs\".",
&CVSCopy::dispatch_string, nullptr, &_cvs_binary);
}
/**
* Checks for the given filename somewhere in the directory hierarchy, and
* chooses a place to import it. Copies the file by calling copy_file().
*
* Extra_data may be NULL or a pointer to some user-defined structure; CVSCopy
* simply passes it unchanged to copy_file(). It presumably gives the class a
* hint as to how the file should be copied. Suggested_dir is the suggested
* directory in which to copy the file, if it does not already exist
* elsewhere.
*
* On success, returns the FilePath it was actually copied to. On failure,
* returns an invalid FilePath.
*/
CVSSourceTree::FilePath CVSCopy::
import(const Filename &source, void *extra_data,
CVSSourceDirectory *suggested_dir) {
CopiedFiles::const_iterator ci;
ci = _copied_files.find(source);
if (ci != _copied_files.end()) {
// We have already copied this file.
return (*ci).second;
}
if (!source.exists()) {
nout << "Source filename " << source << " does not exist!\n";
return CVSSourceTree::FilePath();
}
string basename = filter_filename(source.get_basename());
CVSSourceTree::FilePath path =
_tree.choose_directory(basename, suggested_dir, _force, _interactive);
nassertr(path.is_valid(), path);
_copied_files[source] = path;
Filename dest = path.get_fullpath();
bool new_file = !dest.exists();
if (!new_file && verify_file(source, dest, path._dir, extra_data)) {
// The file is unchanged.
nout << path.get_path() << " is unchanged.\n";
} else {
// The file has changed.
nout << "Copying " << basename << " to " << path.get_path() << "\n";
if (!copy_file(source, dest, path._dir, extra_data, new_file)) {
if (!continue_after_error()) {
return CVSSourceTree::FilePath();
}
} else {
if (new_file) {
cvs_add(dest);
}
}
}
return path;
}
/**
* Prompts the user (unless -f was specified) if he wants to continue the copy
* operation after some error has occurred. Returns true to continue, false
* otherwise.
*/
bool CVSCopy::
continue_after_error() {
if (_force) {
return true;
}
if (_user_aborted) {
return false;
}
while (true) {
string result = prompt("Error occurred during copy! Continue (y/n)? ");
nassertr(!result.empty(), false);
if (result.size() == 1) {
if (tolower(result[0]) == 'y') {
return true;
} else if (tolower(result[0]) == 'n') {
_user_aborted = true;
return false;
}
}
nout << "*** Invalid response: " << result << "\n\n";
}
}
/**
* Does something with the additional arguments on the command line (after all
* the -options have been parsed). Returns true if the arguments are good,
* false otherwise.
*/
bool CVSCopy::
handle_args(Args &args) {
if (args.empty()) {
nout << "You must specify the file(s) to copy from on the command line.\n";
return false;
}
for (Args::const_iterator ai = args.begin();
ai != args.end();
++ai) {
_source_files.push_back(Filename::from_os_specific(*ai));
}
return true;
}
/**
* This is called after the command line has been completely processed, and it
* gives the program a chance to do some last-minute processing and validation
* of the options and arguments. It should return true if everything is fine,
* false if there is an error.
*/
bool CVSCopy::
post_command_line() {
if (!scan_hierarchy()) {
return false;
}
_model_dir = _tree.find_directory(_model_dirname);
if (_model_dir == nullptr) {
if (_got_model_dirname) {
nout << "Warning: model directory " << _model_dirname
<< " is not within the source hierarchy.\n";
}
}
if (_got_map_dirname) {
_map_dir = _tree.find_directory(_map_dirname);
if (_map_dir == nullptr) {
nout << "Warning: map directory " << _map_dirname
<< " is not within the source hierarchy.\n";
}
} else {
_map_dir = _tree.find_relpath("src/maps");
if (_map_dir == nullptr) {
nout << "Warning: no directory " << _tree.get_root_dirname()
<< "/src/maps.\n";
_map_dir = _model_dir;
}
}
return true;
}
/**
* Verifies that the file is identical and does not need to be recopied.
* Returns true if the files are identical, false if they differ.
*/
bool CVSCopy::
verify_file(const Filename &, const Filename &,
CVSSourceDirectory *, void *) {
return false;
}
/**
* Verifies that the file is identical and does not need to be recopied.
* Returns true if the files are identical, false if they differ.
*/
bool CVSCopy::
verify_binary_file(Filename source, Filename dest) {
if (source == dest) {
return true;
}
source.set_binary();
dest.set_binary();
std::ifstream s, d;
if (!source.open_read(s)) {
return false;
}
if (!dest.open_read(d)) {
return false;
}
int cs, cd;
cs = s.get();
cd = d.get();
while (!s.eof() && !s.fail() && !d.eof() && !d.fail()) {
if (cs != cd) {
return false;
}
cs = s.get();
cd = d.get();
}
if (s.fail() || d.fail()) {
// If we had some read error, call the files different.
return false;
}
// If we haven't reached the end of one of the files yet, that file is
// longer than the other one, and the files are therefore different.
if (!s.eof() || !d.eof()) {
return false;
}
// Otherwise, the files are the same.
return true;
}
/**
* Copies a file without modifying it or scanning it in any way. This is
* particularly useful for copying textures. This is provided as a
* convenience function for derived programs because so many model file
* formats will also require copying textures or other black-box files.
*/
bool CVSCopy::
copy_binary_file(Filename source, Filename dest) {
if (source == dest) {
return true;
}
source.set_binary();
dest.set_binary();
std::ifstream in;
std::ofstream out;
if (!source.open_read(in)) {
nout << "Cannot read " << source << "\n";
return false;
}
dest.unlink();
if (!dest.open_write(out)) {
nout << "Cannot write " << dest << "\n";
return false;
}
int c;
c = in.get();
while (!in.eof() && !in.fail() && !out.fail()) {
out.put(c);
c = in.get();
}
if (!in.eof() && in.fail()) {
nout << "Error reading " << source << "\n";
return false;
}
if (out.fail()) {
nout << "Error writing " << dest << "\n";
return false;
}
return true;
}
/**
* Invokes CVS to add the indicated filename to the repository, if the user so
* requested. Returns true if successful, false if there is an error.
*/
bool CVSCopy::
cvs_add(const Filename &filename) {
if (_no_cvs) {
return true;
}
if (!CVSSourceTree::temp_chdir(filename.get_dirname())) {
nout << "Invalid directory: " << filename.get_dirname() << "\n";
return false;
}
string command = _cvs_binary + " add -kb " +
protect_from_shell(filename.get_basename());
nout << command << "\n";
int result = system(command.c_str());
CVSSourceTree::restore_cwd();
if (result != 0) {
nout << "Failure invoking cvs.\n";
return false;
}
return true;
}
/**
* Inserts escape characters into the indicated source string to protect it
* from the shell, so that it may be given on the command line. Returns the
* modified string.
*/
string CVSCopy::
protect_from_shell(const string &source) {
string result;
for (string::const_iterator pi = source.begin(); pi != source.end(); ++pi) {
switch (*pi) {
case '\\':
case ' ':
case '\'':
case '"':
case '(':
case ')':
case '<':
case '>':
case '|':
case '&':
case '!':
case '$':
case '~':
case '*':
case '?':
case '[':
case ']':
case ';':
result += '\\';
// fall through
default:
result += *pi;
}
}
return result;
}
/**
* Given a source filename (including the basename only, without a dirname),
* return the appropriate corresponding filename within the source directory.
* This may be used by derived classes to, for instance, strip a version
* number from the filename.
*/
string CVSCopy::
filter_filename(const string &source) {
return source;
}
/**
* Starts the scan of the source hierarchy. This identifies all of the files
* in the source hierarchy we're to copy these into, so we can guess where
* referenced files should be placed. Returns true if everything is ok, false
* if there is an error.
*/
bool CVSCopy::
scan_hierarchy() {
if (!_got_root_dirname) {
// If we didn't get a root directory name, find the directory above this
// one that contains the file "Package.pp".
if (!scan_for_root(_model_dirname)) {
return false;
}
}
_tree.set_root(_root_dirname);
nout << "Root is " << _tree.get_root_fullpath() << "\n";
return _tree.scan(_key_filename);
}
/**
* Searches for the root of the source directory by looking for the parent
* directory that contains "Package.pp". Returns true on success, false on
* failure.
*/
bool CVSCopy::
scan_for_root(const string &dirname) {
Filename sources = dirname + "/Sources.pp";
if (!sources.exists()) {
nout << "Couldn't find " << sources << " in source directory.\n";
return false;
}
Filename package = dirname + "/Package.pp";
if (package.exists()) {
// Here's the root!
_root_dirname = dirname;
return true;
}
return scan_for_root(dirname + "/..");
}
/**
* Issues a prompt to the user and waits for a typed response. Returns the
* response (which will not be empty).
*/
string CVSCopy::
prompt(const string &message) {
nout << std::flush;
while (true) {
std::cerr << message << std::flush;
std::string response;
std::getline(std::cin, response);
// Remove leading and trailing whitespace.
size_t p = 0;
while (p < response.length() && isspace(response[p])) {
p++;
}
size_t q = response.length();
while (q > p && isspace(response[q - 1])) {
q--;
}
if (q > p) {
return response.substr(p, q - p);
}
}
}

View File

@ -1,89 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cvsCopy.h
* @author drose
* @date 2000-10-31
*/
#ifndef CVSCOPY_H
#define CVSCOPY_H
#include "pandatoolbase.h"
#include "cvsSourceTree.h"
#include "programBase.h"
#include "filename.h"
#include "pvector.h"
/**
* This is the base class for a family of programs that copy files, typically
* model files like .flt files and their associated textures, into a CVS-
* controlled source tree.
*/
class CVSCopy : public ProgramBase {
public:
CVSCopy();
CVSSourceTree::FilePath
import(const Filename &source, void *extra_data,
CVSSourceDirectory *suggested_dir);
bool continue_after_error();
protected:
virtual bool handle_args(Args &args);
virtual bool post_command_line();
virtual bool verify_file(const Filename &source, const Filename &dest,
CVSSourceDirectory *dest_dir,
void *extra_data);
virtual bool copy_file(const Filename &source, const Filename &dest,
CVSSourceDirectory *dest_dir,
void *extra_data, bool new_file)=0;
bool verify_binary_file(Filename source, Filename dest);
bool copy_binary_file(Filename source, Filename dest);
bool cvs_add(const Filename &filename);
static std::string protect_from_shell(const std::string &source);
virtual std::string filter_filename(const std::string &source);
private:
bool scan_hierarchy();
bool scan_for_root(const std::string &dirname);
std::string prompt(const std::string &message);
protected:
bool _force;
bool _interactive;
bool _got_model_dirname;
Filename _model_dirname;
bool _got_map_dirname;
Filename _map_dirname;
bool _got_root_dirname;
Filename _root_dirname;
Filename _key_filename;
bool _no_cvs;
std::string _cvs_binary;
bool _user_aborted;
typedef pvector<Filename> SourceFiles;
SourceFiles _source_files;
CVSSourceTree _tree;
CVSSourceDirectory *_model_dir;
CVSSourceDirectory *_map_dir;
typedef pmap<std::string, CVSSourceTree::FilePath> CopiedFiles;
CopiedFiles _copied_files;
};
#endif

View File

@ -1,237 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cvsSourceDirectory.cxx
* @author drose
* @date 2000-10-31
*/
#include "cvsSourceDirectory.h"
#include "cvsSourceTree.h"
#include "string_utils.h"
#include "pnotify.h"
using std::string;
/**
*
*/
CVSSourceDirectory::
CVSSourceDirectory(CVSSourceTree *tree, CVSSourceDirectory *parent,
const string &dirname) :
_tree(tree),
_parent(parent),
_dirname(dirname)
{
if (_parent == nullptr) {
_depth = 0;
} else {
_depth = _parent->_depth + 1;
}
}
/**
*
*/
CVSSourceDirectory::
~CVSSourceDirectory() {
Children::iterator ci;
for (ci = _children.begin(); ci != _children.end(); ++ci) {
delete (*ci);
}
}
/**
* Returns the local name of this particular directory.
*/
string CVSSourceDirectory::
get_dirname() const {
return _dirname;
}
/**
* Returns the full pathname to this particular directory.
*/
Filename CVSSourceDirectory::
get_fullpath() const {
if (_parent == nullptr) {
return _tree->get_root_fullpath();
}
return Filename(_parent->get_fullpath(), _dirname);
}
/**
* Returns the relative pathname to this particular directory, as seen from
* the root of the tree.
*/
Filename CVSSourceDirectory::
get_path() const {
if (_parent == nullptr) {
return _dirname;
}
return Filename(_parent->get_path(), _dirname);
}
/**
* Returns the relative path to the other directory from this one. This does
* not include a trailing slash.
*/
Filename CVSSourceDirectory::
get_rel_to(const CVSSourceDirectory *other) const {
const CVSSourceDirectory *a = this;
const CVSSourceDirectory *b = other;
if (a == b) {
return ".";
}
string prefix, postfix;
while (a->_depth > b->_depth) {
prefix += "../";
a = a->_parent;
nassertr(a != nullptr, string());
}
while (b->_depth > a->_depth) {
postfix = b->_dirname + "/" + postfix;
b = b->_parent;
nassertr(b != nullptr, string());
}
while (a != b) {
prefix += "../";
postfix = b->_dirname + "/" + postfix;
a = a->_parent;
b = b->_parent;
nassertr(a != nullptr, string());
nassertr(b != nullptr, string());
}
string result = prefix + postfix;
nassertr(!result.empty(), string());
return result.substr(0, result.length() - 1);
}
/**
* Returns the number of subdirectories below this directory.
*/
int CVSSourceDirectory::
get_num_children() const {
return _children.size();
}
/**
* Returns the nth subdirectory below this directory.
*/
CVSSourceDirectory *CVSSourceDirectory::
get_child(int n) const {
nassertr(n >= 0 && n < (int)_children.size(), nullptr);
return _children[n];
}
/**
* Returns the source directory that corresponds to the given relative path
* from this directory, or NULL if there is no match.
*/
CVSSourceDirectory *CVSSourceDirectory::
find_relpath(const string &relpath) {
if (relpath.empty()) {
return this;
}
size_t slash = relpath.find('/');
string first = relpath.substr(0, slash);
string rest;
if (slash != string::npos) {
rest = relpath.substr(slash + 1);
}
if (first.empty() || first == ".") {
return find_relpath(rest);
} else if (first == "..") {
if (_parent != nullptr) {
return _parent->find_relpath(rest);
}
// Tried to back out past the root directory.
return nullptr;
}
// Check for a child with the name indicated by first.
Children::const_iterator ci;
for (ci = _children.begin(); ci != _children.end(); ++ci) {
if (cmp_nocase((*ci)->get_dirname(), first) == 0) {
return (*ci)->find_relpath(rest);
}
}
// No match.
return nullptr;
}
/**
* Returns the source directory that corresponds to the given local directory
* name, or NULL if there is no match.
*/
CVSSourceDirectory *CVSSourceDirectory::
find_dirname(const string &dirname) {
if (cmp_nocase(dirname, _dirname) == 0) {
return this;
}
Children::const_iterator ci;
for (ci = _children.begin(); ci != _children.end(); ++ci) {
CVSSourceDirectory *result = (*ci)->find_dirname(dirname);
if (result != nullptr) {
return result;
}
}
return nullptr;
}
/**
* Recursively scans the contents of the source directory. Fullpath is the
* full path name to the directory; key_filename is the name of a file that
* must exist in each subdirectory for it to be considered part of the
* hierarchy. Returns true on success, false on failure.
*/
bool CVSSourceDirectory::
scan(const Filename &directory, const string &key_filename) {
vector_string contents;
if (!directory.scan_directory(contents)) {
nout << "Unable to scan directory " << directory << "\n";
return false;
}
vector_string::const_iterator fi;
for (fi = contents.begin(); fi != contents.end(); ++fi) {
const string &basename = (*fi);
// Is this possibly a subdirectory name?
Filename next_path(directory, basename);
Filename key(next_path, key_filename);
if (key.exists()) {
CVSSourceDirectory *subdir =
new CVSSourceDirectory(_tree, this, basename);
_children.push_back(subdir);
if (!subdir->scan(next_path, key_filename)) {
return false;
}
} else {
// It's not a subdirectory; call it a regular file.
_tree->add_file(basename, this);
}
}
return true;
}

View File

@ -1,65 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cvsSourceDirectory.h
* @author drose
* @date 2000-10-31
*/
#ifndef CVSSOURCEDIRECTORY_H
#define CVSSOURCEDIRECTORY_H
#include "pandatoolbase.h"
#include "filename.h"
#include "pvector.h"
class CVSSourceTree;
/**
* This represents one particular directory in the hierarchy of source
* directory files. We must scan the source directory to identify where the
* related files have previously been copied.
*
* The tree is maintained in a case-insensitive manner, even on a non-Windows
* system, since you might want to eventually check out the CVS tree onto a
* Windows system--and if you do, you'll be sad if there are case conflicts
* within the tree. So we make an effort to ensure this doesn't happen by
* treating two files with a different case as the same file.
*/
class CVSSourceDirectory {
public:
CVSSourceDirectory(CVSSourceTree *tree, CVSSourceDirectory *parent,
const std::string &dirname);
~CVSSourceDirectory();
std::string get_dirname() const;
Filename get_fullpath() const;
Filename get_path() const;
Filename get_rel_to(const CVSSourceDirectory *other) const;
int get_num_children() const;
CVSSourceDirectory *get_child(int n) const;
CVSSourceDirectory *find_relpath(const std::string &relpath);
CVSSourceDirectory *find_dirname(const std::string &dirname);
public:
bool scan(const Filename &directory, const std::string &key_filename);
private:
CVSSourceTree *_tree;
CVSSourceDirectory *_parent;
std::string _dirname;
int _depth;
typedef pvector<CVSSourceDirectory *> Children;
Children _children;
};
#endif

View File

@ -1,546 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cvsSourceTree.cxx
* @author drose
* @date 2000-10-31
*/
#include "cvsSourceTree.h"
#include "cvsSourceDirectory.h"
#include "filename.h"
#include "executionEnvironment.h"
#include "pnotify.h"
#include "string_utils.h"
#include <algorithm>
#include <ctype.h>
#include <stdio.h> // for perror
#include <errno.h>
#ifdef WIN32_VC
#include <direct.h> // for chdir
#endif
using std::string;
bool CVSSourceTree::_got_start_fullpath = false;
Filename CVSSourceTree::_start_fullpath;
/**
*
*/
CVSSourceTree::
CVSSourceTree() {
_root = nullptr;
_got_root_fullpath = false;
}
/**
*
*/
CVSSourceTree::
~CVSSourceTree() {
if (_root != nullptr) {
delete _root;
}
}
/**
* Sets the root of the source directory. This must be called before scan(),
* and should not be called more than once.
*/
void CVSSourceTree::
set_root(const Filename &root_path) {
nassertv(_path.empty());
_path = root_path;
}
/**
* Scans the complete source directory starting at the indicated pathname. It
* is an error to call this more than once. Returns true on success, false if
* there is an error.
*/
bool CVSSourceTree::
scan(const Filename &key_filename) {
nassertr(_root == nullptr, false);
Filename root_fullpath = get_root_fullpath();
_root = new CVSSourceDirectory(this, nullptr, root_fullpath.get_basename());
return _root->scan(_path, key_filename);
}
/**
* Returns the root directory of the hierarchy.
*/
CVSSourceDirectory *CVSSourceTree::
get_root() const {
return _root;
}
/**
* Returns the source directory that corresponds to the given path, or NULL if
* there is no such directory in the source tree.
*/
CVSSourceDirectory *CVSSourceTree::
find_directory(const Filename &path) {
string root_fullpath = get_root_fullpath();
string fullpath = get_actual_fullpath(path);
// path is a subdirectory within the source hierarchy if and only if
// root_fullpath is an initial prefix of fullpath.
if (root_fullpath.length() > fullpath.length() ||
cmp_nocase(fullpath.substr(0, root_fullpath.length()), root_fullpath) != 0) {
// Nope!
return nullptr;
}
// The relative name is the part of fullpath not in root_fullpath.
Filename relpath = fullpath.substr(root_fullpath.length());
return _root->find_relpath(relpath);
}
/**
* Returns the source directory that corresponds to the given relative path
* from the root, or NULL if there is no match. The relative path may or may
* not include the name of the root directory itself.
*/
CVSSourceDirectory *CVSSourceTree::
find_relpath(const string &relpath) {
CVSSourceDirectory *result = _root->find_relpath(relpath);
if (result != nullptr) {
return result;
}
// Check for the root dirname at the front of the path, and remove it if
// it's there.
size_t slash = relpath.find('/');
Filename first = relpath.substr(0, slash);
Filename rest;
if (slash != string::npos) {
rest = relpath.substr(slash + 1);
}
if (cmp_nocase(first, _root->get_dirname()) == 0) {
return _root->find_relpath(rest);
}
return nullptr;
}
/**
* Returns the source directory that corresponds to the given local directory
* name, or NULL if there is no match.
*/
CVSSourceDirectory *CVSSourceTree::
find_dirname(const string &dirname) {
return _root->find_dirname(dirname);
}
/**
* Determines where an externally referenced model file of the indicated name
* should go. It does this by looking for an existing model file of the same
* name; if a matching model is not found, or if multiple matching files are
* found, prompts the user for the directory, or uses suggested_dir.
*/
CVSSourceTree::FilePath CVSSourceTree::
choose_directory(const string &basename, CVSSourceDirectory *suggested_dir,
bool force, bool interactive) {
static FilePaths empty_paths;
Basenames::const_iterator bi;
bi = _basenames.find(downcase(basename));
if (bi != _basenames.end()) {
// The filename already exists somewhere.
const FilePaths &paths = (*bi).second;
return prompt_user(basename, suggested_dir, paths,
force, interactive);
}
// Now we have to prompt the user for a suitable place to put it.
return prompt_user(basename, suggested_dir, empty_paths,
force, interactive);
}
/**
* Returns the full path from the root to the top of the source hierarchy.
*/
Filename CVSSourceTree::
get_root_fullpath() {
nassertr(!_path.empty(), Filename());
if (!_got_root_fullpath) {
_root_fullpath = get_actual_fullpath(_path);
_got_root_fullpath = true;
}
return _root_fullpath;
}
/**
* Returns the local directory name of the root of the tree.
*/
Filename CVSSourceTree::
get_root_dirname() const {
nassertr(_root != nullptr, Filename());
return _root->get_dirname();
}
/**
* Adds a new file to the set of known files. This is normally called from
* CVSSourceDirectory::scan() and should not be called directly by the user.
*/
void CVSSourceTree::
add_file(const string &basename, CVSSourceDirectory *dir) {
FilePath file_path(dir, basename);
_basenames[downcase(basename)].push_back(file_path);
}
/**
* Temporarily changes the current directory to the named path. Returns true
* on success, false on failure. Call restore_cwd() to restore to the
* original directory later.
*/
bool CVSSourceTree::
temp_chdir(const Filename &path) {
// We have to call this first to guarantee that we have already determined
// our starting directory.
get_start_fullpath();
string os_path = path.to_os_specific();
if (chdir(os_path.c_str()) < 0) {
return false;
}
return true;
}
/**
* Restores the current directory after changing it from temp_chdir().
*/
void CVSSourceTree::
restore_cwd() {
Filename start_fullpath = get_start_fullpath();
string os_path = start_fullpath.to_os_specific();
if (chdir(os_path.c_str()) < 0) {
// Hey! We can't get back to the directory we started from!
perror(os_path.c_str());
nout << "Can't continue, aborting.\n";
exit(1);
}
}
/**
* Prompts the user, if necessary, to choose a directory to import the given
* file into.
*/
CVSSourceTree::FilePath CVSSourceTree::
prompt_user(const string &basename, CVSSourceDirectory *suggested_dir,
const CVSSourceTree::FilePaths &paths,
bool force, bool interactive) {
if (paths.size() == 1) {
// The file already exists in exactly one place.
if (!interactive) {
return paths[0];
}
FilePath result = ask_existing(basename, paths[0]);
if (result.is_valid()) {
return result;
}
} else if (paths.size() > 1) {
// The file already exists in multiple places.
if (force && !interactive) {
return paths[0];
}
FilePath result = ask_existing(basename, paths, suggested_dir);
if (result.is_valid()) {
return result;
}
}
// The file does not already exist, or the user declined to replace an
// existing file.
if (force && !interactive) {
return FilePath(suggested_dir, basename);
}
// Is the file already in the suggested directory? If not, prompt the user
// to put it there.
bool found_dir = false;
FilePaths::const_iterator pi;
for (pi = paths.begin(); pi != paths.end(); ++pi) {
if ((*pi)._dir == suggested_dir) {
found_dir = true;
break;
}
}
if (!found_dir) {
FilePath result = ask_new(basename, suggested_dir);
if (result.is_valid()) {
return result;
}
}
// Ask the user where the damn thing should go.
return ask_any(basename, paths);
}
/**
* Asks the user if he wants to replace an existing file.
*/
CVSSourceTree::FilePath CVSSourceTree::
ask_existing(const string &basename, const CVSSourceTree::FilePath &path) {
while (true) {
nout << basename << " found in tree at "
<< path.get_path() << ".\n";
string result = prompt("Overwrite this file (y/n)? ");
nassertr(!result.empty(), FilePath());
if (result.size() == 1) {
if (tolower(result[0]) == 'y') {
return path;
} else if (tolower(result[0]) == 'n') {
return FilePath();
}
}
nout << "*** Invalid response: " << result << "\n\n";
}
}
/**
* Asks the user which of several existing files he wants to replace.
*/
CVSSourceTree::FilePath CVSSourceTree::
ask_existing(const string &basename, const CVSSourceTree::FilePaths &paths,
CVSSourceDirectory *suggested_dir) {
while (true) {
nout << basename << " found in tree at more than one place:\n";
bool any_suggested = false;
for (int i = 0; i < (int)paths.size(); i++) {
nout << " " << (i + 1) << ". "
<< paths[i].get_path() << "\n";
if (paths[i]._dir == suggested_dir) {
any_suggested = true;
}
}
int next_option = paths.size() + 1;
int suggested_option = -1;
if (!any_suggested) {
// If it wasn't already in the suggested directory, offer to put it
// there.
suggested_option = next_option;
next_option++;
nout << "\n" << suggested_option
<< ". create "
<< Filename(suggested_dir->get_path(), basename)
<< "\n";
}
int other_option = next_option;
nout << other_option << ". Other\n";
string result = prompt("Choose an option: ");
nassertr(!result.empty(), FilePath());
const char *nptr = result.c_str();
char *endptr;
int option = strtol(nptr, &endptr, 10);
if (*endptr == '\0') {
if (option >= 1 && option <= (int)paths.size()) {
return paths[option - 1];
} else if (option == suggested_option) {
return FilePath(suggested_dir, basename);
} else if (option == other_option) {
return FilePath();
}
}
nout << "*** Invalid response: " << result << "\n\n";
}
}
/**
* Asks the user if he wants to create a new file.
*/
CVSSourceTree::FilePath CVSSourceTree::
ask_new(const string &basename, CVSSourceDirectory *dir) {
while (true) {
nout << basename << " will be created in "
<< dir->get_path() << ".\n";
string result = prompt("Create this file (y/n)? ");
nassertr(!result.empty(), FilePath());
if (result.size() == 1) {
if (tolower(result[0]) == 'y') {
return FilePath(dir, basename);
} else if (tolower(result[0]) == 'n') {
return FilePath();
}
}
nout << "*** Invalid response: " << result << "\n\n";
}
}
/**
* Asks the user to type in the name of the directory in which to store the
* file.
*/
CVSSourceTree::FilePath CVSSourceTree::
ask_any(const string &basename,
const CVSSourceTree::FilePaths &paths) {
while (true) {
string result =
prompt("Enter the name of the directory to copy " + basename + " to: ");
nassertr(!result.empty(), FilePath());
// The user might enter a fully-qualified path to the directory, or a
// relative path from the root (with or without the root's dirname), or
// the dirname of the particular directory.
CVSSourceDirectory *dir = find_directory(result);
if (dir == nullptr) {
dir = find_relpath(result);
}
if (dir == nullptr) {
dir = find_dirname(result);
}
if (dir != nullptr) {
// If the file is already in this directory, we must preserve its
// existing case.
FilePaths::const_iterator pi;
for (pi = paths.begin(); pi != paths.end(); ++pi) {
if ((*pi)._dir == dir) {
return (*pi);
}
}
// Otherwise, since we're creating a new file, keep the original case.
return FilePath(dir, basename);
}
nout << "*** Not a valid directory name: " << result << "\n\n";
}
}
/**
* Issues a prompt to the user and waits for a typed response. Returns the
* response (which will not be empty).
*/
string CVSSourceTree::
prompt(const string &message) {
nout << std::flush;
while (true) {
std::cerr << message << std::flush;
std::string response;
std::getline(std::cin, response);
// Remove leading and trailing whitespace.
size_t p = 0;
while (p < response.length() && isspace(response[p])) {
p++;
}
size_t q = response.length();
while (q > p && isspace(response[q - 1])) {
q--;
}
if (q > p) {
return response.substr(p, q - p);
}
}
}
/**
* Determines the actual full path from the root to the named directory.
*/
Filename CVSSourceTree::
get_actual_fullpath(const Filename &path) {
Filename canon = path;
canon.make_canonical();
return canon;
}
/**
* Returns the full path from the root to the directory in which the user
* started the program.
*/
Filename CVSSourceTree::
get_start_fullpath() {
if (!_got_start_fullpath) {
Filename cwd = ExecutionEnvironment::get_cwd();
_start_fullpath = cwd.to_os_specific();
}
return _start_fullpath;
}
/**
* Creates an invalid FilePath specification.
*/
CVSSourceTree::FilePath::
FilePath() :
_dir(nullptr)
{
}
/**
* Creates a valid FilePath specification with the indicated directory and
* basename.
*/
CVSSourceTree::FilePath::
FilePath(CVSSourceDirectory *dir, const string &basename) :
_dir(dir),
_basename(basename)
{
}
/**
* Returns true if this FilePath represents a valid file, or false if it
* represents an error return.
*/
bool CVSSourceTree::FilePath::
is_valid() const {
return (_dir != nullptr);
}
/**
* Returns the relative path to this file from the root of the source tree.
*/
Filename CVSSourceTree::FilePath::
get_path() const {
nassertr(_dir != nullptr, Filename());
return Filename(_dir->get_path(), _basename);
}
/**
* Returns the full path to this file.
*/
Filename CVSSourceTree::FilePath::
get_fullpath() const {
nassertr(_dir != nullptr, Filename());
return Filename(_dir->get_fullpath(), _basename);
}
/**
* Returns the relative path to this file as seen from the indicated source
* directory.
*/
Filename CVSSourceTree::FilePath::
get_rel_from(const CVSSourceDirectory *other) const {
nassertr(_dir != nullptr, Filename());
return Filename(other->get_rel_to(_dir), _basename);
}

View File

@ -1,109 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file cvsSourceTree.h
* @author drose
* @date 2000-10-31
*/
#ifndef CVSSOURCETREE_H
#define CVSSOURCETREE_H
#include "pandatoolbase.h"
#include "pvector.h"
#include "pmap.h"
#include "filename.h"
class CVSSourceDirectory;
/**
* This represents the root of the tree of source directory files.
*
* The tree is maintained in a case-insensitive manner, even on a non-Windows
* system, since you might want to eventually check out the CVS tree onto a
* Windows system--and if you do, you'll be sad if there are case conflicts
* within the tree. So we make an effort to ensure this doesn't happen by
* treating two files with a different case as the same file.
*/
class CVSSourceTree {
public:
CVSSourceTree();
~CVSSourceTree();
void set_root(const Filename &root_path);
bool scan(const Filename &key_filename);
CVSSourceDirectory *get_root() const;
CVSSourceDirectory *find_directory(const Filename &path);
CVSSourceDirectory *find_relpath(const std::string &relpath);
CVSSourceDirectory *find_dirname(const std::string &dirname);
// This nested class represents the selection of a particular directory in
// which to place a given file, given its basename. The basename of the
// file is returned as part of the answer, because it might have changed in
// case from the original basename (in order to match the case of an
// existing file in the selected directory).
class FilePath {
public:
FilePath();
FilePath(CVSSourceDirectory *dir, const std::string &basename);
bool is_valid() const;
Filename get_path() const;
Filename get_fullpath() const;
Filename get_rel_from(const CVSSourceDirectory *other) const;
CVSSourceDirectory *_dir;
std::string _basename;
};
FilePath choose_directory(const std::string &basename,
CVSSourceDirectory *suggested_dir,
bool force, bool interactive);
Filename get_root_fullpath();
Filename get_root_dirname() const;
static bool temp_chdir(const Filename &path);
static void restore_cwd();
public:
void add_file(const std::string &basename, CVSSourceDirectory *dir);
private:
typedef pvector<FilePath> FilePaths;
FilePath
prompt_user(const std::string &basename, CVSSourceDirectory *suggested_dir,
const FilePaths &paths, bool force, bool interactive);
FilePath ask_existing(const std::string &filename, const FilePath &path);
FilePath ask_existing(const std::string &filename, const FilePaths &paths,
CVSSourceDirectory *suggested_dir);
FilePath ask_new(const std::string &filename, CVSSourceDirectory *dir);
FilePath ask_any(const std::string &filename, const FilePaths &paths);
std::string prompt(const std::string &message);
static Filename get_actual_fullpath(const Filename &path);
static Filename get_start_fullpath();
private:
Filename _path;
CVSSourceDirectory *_root;
typedef pmap<std::string, FilePaths> Basenames;
Basenames _basenames;
static bool _got_start_fullpath;
static Filename _start_fullpath;
bool _got_root_fullpath;
Filename _root_fullpath;
};
#endif

View File

@ -1,5 +0,0 @@
#include "cvsCopy.cxx"
#include "cvsSourceDirectory.cxx"
#include "cvsSourceTree.cxx"

View File

@ -1,65 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file testCopy.cxx
* @author drose
* @date 2000-10-31
*/
#include "testCopy.h"
#include "cvsSourceDirectory.h"
/**
*
*/
TestCopy::
TestCopy() {
set_program_brief("copy files into a CVS source hierarchy");
set_program_description
("This program copies one or more files into a CVS source hierarchy. "
"Rather than copying the named files immediately into the current "
"directory, it first scans the entire source hierarchy, identifying all "
"the already-existing files. If the named file to copy matches the "
"name of an already-existing file in the current directory or elsewhere "
"in the hierarchy, that file is overwritten.\n\n"
"This is primarily useful as a test program for libcvscopy.");
}
/**
*
*/
void TestCopy::
run() {
SourceFiles::iterator fi;
for (fi = _source_files.begin(); fi != _source_files.end(); ++fi) {
CVSSourceDirectory *dest = import(*fi, 0, _model_dir);
if (dest == nullptr) {
exit(1);
}
}
}
/**
* Called by import() if the timestamps indicate that a file needs to be
* copied. This does the actual copy of a file from source to destination.
* If new_file is true, then dest does not already exist.
*/
bool TestCopy::
copy_file(const Filename &source, const Filename &dest,
CVSSourceDirectory *, void *, bool) {
return copy_binary_file(source, dest);
}
int main(int argc, char *argv[]) {
TestCopy prog;
prog.parse_command_line(argc, argv);
prog.run();
return 0;
}

View File

@ -1,37 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file testCopy.h
* @author drose
* @date 2000-10-31
*/
#ifndef TESTCOPY_H
#define TESTCOPY_H
#include "pandatoolbase.h"
#include "cvsCopy.h"
/**
* A program to copy ordinary files into the cvs tree. Mainly to test
* CVSCopy.
*/
class TestCopy : public CVSCopy {
public:
TestCopy();
void run();
protected:
virtual bool copy_file(const Filename &source, const Filename &dest,
CVSSourceDirectory *dir, void *extra_data,
bool new_file);
};
#endif

View File

@ -1,237 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file fltCopy.cxx
* @author drose
* @date 2000-11-01
*/
#include "fltCopy.h"
#include "cvsSourceDirectory.h"
#include "fltHeader.h"
#include "fltFace.h"
#include "fltExternalReference.h"
#include "fltError.h"
#include "dcast.h"
/**
*
*/
FltCopy::
FltCopy() {
set_program_brief("copy MultiGen .flt files into a CVS source hierarchy");
set_program_description
("fltcopy copies one or more MultiGen .flt files into a "
"CVS source hierarchy. "
"Rather than copying the named files immediately into the current "
"directory, it first scans the entire source hierarchy, identifying all "
"the already-existing files. If the named file to copy matches the "
"name of an already-existing file in the current directory or elsewhere "
"in the hierarchy, that file is overwritten. Other .flt files, as "
"well as texture files, that are externally referenced by the "
"named .flt file(s) are similarly copied.");
clear_runlines();
add_runline("[opts] file.flt [file.flt ... ]");
add_path_replace_options();
}
/**
*
*/
void FltCopy::
run() {
SourceFiles::iterator fi;
for (fi = _source_files.begin(); fi != _source_files.end(); ++fi) {
ExtraData ed;
ed._type = FT_flt;
CVSSourceTree::FilePath dest = import(*fi, &ed, _model_dir);
if (!dest.is_valid()) {
exit(1);
}
}
}
/**
* Called by import() if verify_file() indicates that a file needs to be
* copied. This does the actual copy of a file from source to destination.
* If new_file is true, then dest does not already exist.
*/
bool FltCopy::
copy_file(const Filename &source, const Filename &dest,
CVSSourceDirectory *dir, void *extra_data, bool new_file) {
ExtraData *ed = (ExtraData *)extra_data;
switch (ed->_type) {
case FT_flt:
return copy_flt_file(source, dest, dir);
case FT_texture:
return copy_texture(source, dest, dir, ed->_texture, new_file);
}
nout << "Internal error: invalid type " << (int)ed->_type << "\n";
return false;
}
/**
*
*/
bool FltCopy::
copy_flt_file(const Filename &source, const Filename &dest,
CVSSourceDirectory *dir) {
PT(FltHeader) header = new FltHeader(_path_replace);
// We don't want to automatically generate .attr files--we'd rather write
// them out explicitly.
header->set_auto_attr_update(FltHeader::AU_none);
FltError result = header->read_flt(source);
if (result != FE_ok) {
nout << "Cannot read " << source << ": " << result << "\n";
return false;
}
header->check_version();
// Now scan the flt file for nested references.
Refs refs;
Textures textures;
scan_flt(header, refs, textures);
Refs::const_iterator ri;
for (ri = refs.begin(); ri != refs.end(); ++ri) {
FltExternalReference *ref = (*ri);
Filename ref_filename = ref->get_ref_filename();
if (!ref_filename.exists()) {
nout << "*** Warning: external reference " << ref_filename
<< " does not exist.\n";
} else {
ExtraData ed;
ed._type = FT_flt;
CVSSourceTree::FilePath ref_path =
import(ref_filename, &ed, _model_dir);
if (!ref_path.is_valid()) {
return false;
}
// Update the reference to point to the new flt filename, relative to
// the base flt file.
ref->set_ref_filename(ref_path.get_rel_from(dir));
}
}
// Remove all the textures from the palette, and then add back only those we
// found in use. This way we don't copy a file that references bogus
// textures.
header->clear_textures();
Textures::const_iterator ti;
for (ti = textures.begin(); ti != textures.end(); ++ti) {
FltTexture *tex = (*ti);
Filename texture_filename = tex->get_texture_filename();
if (!texture_filename.exists()) {
nout << "*** Warning: texture " << texture_filename
<< " does not exist.\n";
} else {
ExtraData ed;
ed._type = FT_texture;
ed._texture = tex;
CVSSourceTree::FilePath texture_path =
import(texture_filename, &ed, _map_dir);
if (!texture_path.is_valid()) {
return false;
}
// Update the texture reference to point to the new texture filename,
// relative to the flt file.
tex->set_texture_filename(texture_path.get_rel_from(dir));
header->add_texture(tex);
}
}
// Finally, write the resulting file out.
result = header->write_flt(dest);
if (result != FE_ok) {
nout << "Cannot write " << dest << "\n";
return false;
}
return true;
}
/**
*
*/
bool FltCopy::
copy_texture(const Filename &source, const Filename &dest,
CVSSourceDirectory *dir, FltTexture *tex, bool new_file) {
if (!copy_binary_file(source, dest)) {
return false;
}
// Also write out the .attr file.
Filename attr_filename = dest.get_fullpath() + ".attr";
if (!attr_filename.exists()) {
new_file = true;
}
tex->write_attr_data(attr_filename);
if (new_file) {
cvs_add(attr_filename);
}
return true;
}
/**
* Recursively walks through the flt file hierarchy, looking for texture
* references and external flt file references.
*/
void FltCopy::
scan_flt(FltRecord *record, FltCopy::Refs &refs, FltCopy::Textures &textures) {
if (record->is_of_type(FltFace::get_class_type())) {
FltFace *face;
DCAST_INTO_V(face, record);
if (face->has_texture()) {
textures.insert(face->get_texture());
}
} else if (record->is_of_type(FltExternalReference::get_class_type())) {
FltExternalReference *ref;
DCAST_INTO_V(ref, record);
refs.insert(ref);
}
int i;
int num_subfaces = record->get_num_subfaces();
for (i = 0; i < num_subfaces; i++) {
scan_flt(record->get_subface(i), refs, textures);
}
int num_children = record->get_num_children();
for (i = 0; i < num_children; i++) {
scan_flt(record->get_child(i), refs, textures);
}
}
int main(int argc, char *argv[]) {
FltCopy prog;
prog.parse_command_line(argc, argv);
prog.run();
return 0;
}

View File

@ -1,70 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file fltCopy.h
* @author drose
* @date 2000-11-01
*/
#ifndef FLTCOPY_H
#define FLTCOPY_H
#include "pandatoolbase.h"
#include "cvsCopy.h"
#include "dSearchPath.h"
#include "pointerTo.h"
#include "pset.h"
class FltRecord;
class FltTexture;
class FltExternalReference;
/**
* A program to copy Multigen .flt files into the cvs tree. It copies the
* base file plus all externally referenced files as well as all textures.
*/
class FltCopy : public CVSCopy {
public:
FltCopy();
void run();
protected:
virtual bool copy_file(const Filename &source, const Filename &dest,
CVSSourceDirectory *dir, void *extra_data,
bool new_file);
private:
enum FileType {
FT_flt,
FT_texture
};
class ExtraData {
public:
FileType _type;
FltTexture *_texture;
};
bool copy_flt_file(const Filename &source, const Filename &dest,
CVSSourceDirectory *dir);
bool copy_texture(const Filename &source, const Filename &dest,
CVSSourceDirectory *dir, FltTexture *tex,
bool new_file);
typedef pset< PT(FltExternalReference) > Refs;
typedef pset< PT(FltTexture) > Textures;
void scan_flt(FltRecord *record, Refs &refs, Textures &textures);
};
#endif

View File

@ -1,457 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file mayaCopy.cxx
* @author drose
* @date 2002-05-10
* Modified 19Mar10 by ETC PandaSE team (see
* header comment for mayaToEgg.cxx for more details)
*/
#include "mayaCopy.h"
#include "config_maya.h"
#include "cvsSourceDirectory.h"
#include "dcast.h"
#include "pre_maya_include.h"
#include <maya/MStringArray.h>
#include <maya/MGlobal.h>
#include <maya/MFileIO.h>
#include <maya/MItDag.h>
#include <maya/MFnDagNode.h>
#include <maya/MFnNurbsSurface.h>
#include <maya/MFnMesh.h>
#include <maya/MObject.h>
#include <maya/MDagPath.h>
#include <maya/MIntArray.h>
#include "post_maya_include.h"
#include "mayaShader.h"
using std::endl;
using std::string;
/**
*
*/
MayaCopy::
MayaCopy() {
set_program_brief("copy Maya .mb files into a CVS source hierarchy");
set_program_description
("mayacopy copies one or more Maya .mb files into a "
"CVS source hierarchy. "
"Rather than copying the named files immediately into the current "
"directory, it first scans the entire source hierarchy, identifying all "
"the already-existing files. If the named file to copy matches the "
"name of an already-existing file in the current directory or elsewhere "
"in the hierarchy, that file is overwritten. Other .mb files, as "
"well as texture files, that are externally referenced by the "
"named .mb file(s) are similarly copied.");
clear_runlines();
add_runline("[opts] file.mb [file.mb ... ]");
add_option
("keepver", "", 0,
"Don't attempt to strip the Maya version number from the tail of the "
"source filename before it is copied into the tree.",
&CVSCopy::dispatch_none, &_keep_ver);
/*
add_option
("rp", "replace_prefix", 80,
"use these prefixes when replacing reference with the recently copied file from the "
"source filename before it is copied into the tree.",
&CVSCopy::dispatch_vector_string, NULL, &_replace_prefix);
*/
add_option
("omittex", "", 0,
"Character animation files do not need to copy the texures. "
"This option omits the textures of the models to be re-mayacopied",
&CVSCopy::dispatch_none, &_omit_tex);
add_option
("omitref", "", 0,
"Character animation files do not need to copy internal file references. "
"This option omits the references of the models to be re-mayacopied",
&CVSCopy::dispatch_none, &_omit_ref);
add_option
("ma", "", 0,
"Write a .ma file instead of a .mb file (regardless of input type)",
&CVSCopy::dispatch_none, &_maya_ascii);
add_path_replace_options();
}
/**
*
*/
void MayaCopy::
run() {
_maya = MayaApi::open_api(_program_name);
if (!_maya->is_valid()) {
nout << "Unable to initialize Maya.\n";
exit(1);
}
SourceFiles::iterator fi;
for (fi = _source_files.begin(); fi != _source_files.end(); ++fi) {
_curr_idx = 0;
ExtraData ed;
ed._type = FT_maya;
CVSSourceTree::FilePath path = import(*fi, &ed, _model_dir);
if (!path.is_valid()) {
nout << "\nUnable to copy, aborting!\n\n";
exit(1);
}
}
}
/**
* Called by import() if verify_file() indicates that a file needs to be
* copied. This does the actual copy of a file from source to destination.
* If new_file is true, then dest does not already exist.
*/
bool MayaCopy::
copy_file(const Filename &source, const Filename &dest,
CVSSourceDirectory *dir, void *extra_data, bool new_file) {
ExtraData *ed = (ExtraData *)extra_data;
switch (ed->_type) {
case FT_maya:
return copy_maya_file(source, dest, dir);
case FT_texture:
if (_omit_tex) {
return true;
}
return copy_texture(source, dest, dir);
}
nout << "Internal error: invalid type " << (int)ed->_type << "\n";
return false;
}
/**
* Given a source filename (including the basename only, without a dirname),
* return the appropriate corresponding filename within the source directory.
* This may be used by derived classes to, for instance, strip a version
* number from the filename.
*/
string MayaCopy::
filter_filename(const string &source) {
if (_keep_ver) {
return source;
}
size_t dot = source.rfind('.');
size_t underscore = source.rfind("_v", dot);
if ((underscore != string::npos) && !isdigit(source.at(underscore+2)))
underscore = string::npos;
string extension = source.substr(dot);
if (extension == ".ma" || extension == ".mb") {
// If we are reading a Maya file (as opposed to a texture image), then we
// always write ".mb" files out (unless -ma was specified on the command
// line).
if (_maya_ascii) {
extension = ".ma";
} else {
extension = ".mb";
}
}
if (underscore == string::npos) {
// No version number appears to be present.
return source.substr(0, dot) + extension;
} else {
return source.substr(0, underscore) + extension;
}
}
/**
*
*/
bool MayaCopy::
copy_maya_file(const Filename &source, const Filename &dest,
CVSSourceDirectory *dir) {
if (!_maya->read(source)) {
maya_cat.error()
<< "Unable to read " << source << "\n";
return false;
}
// Get the set of externally referenced Maya files.
MStringArray refs;
MStatus status = MFileIO::getReferences(refs);
if (status != MStatus::kSuccess) {
status.perror("MItDag constructor");
return false;
}
// Finally, copy in any referenced Maya files.
unsigned int num_refs = refs.length();
unsigned int ref_index;
maya_cat.info() << "num_refs = " << num_refs << endl;
for (ref_index = 0; ref_index < num_refs; ref_index++) {
maya_cat.info() << "curr_idx " << _curr_idx << endl;
string lookup = refs[ref_index].asChar();
string blah = "file -q -referenceNode \"" + lookup + "\";";
maya_cat.info() << blah << endl;
MString result;
status = MGlobal::executeCommand(MString(blah.c_str()), result);
maya_cat.info() << "result = " << result.asChar() << endl;
// for multiple reference of the same model. maya throws in a {#} at the
// end, ignore that
size_t dup = lookup.find('{');
if (dup != string::npos){
lookup.erase(dup);
}
// to check out this specific reference is actually loaded or not somehow
// this flag order of MEL script must be observed to guarantee proper
// working
string refNode = result.asChar();
string refCheckCmd = "file -rfn " + refNode + " -q -dr;";
int deferredRef;
status = MGlobal::executeCommand(MString(refCheckCmd.c_str()), deferredRef);
maya_cat.info() << "deferredRef = " << deferredRef << endl;
if (deferredRef == 1) { // means this reference is deferred, unloaded
continue;
}
Filename filename =
_path_replace->convert_path(Filename::from_os_specific(lookup));
CVSSourceTree::FilePath path =
_tree.choose_directory(filename.get_basename(), dir, _force, _interactive);
Filename new_filename = path.get_rel_from(dir);
if (maya_cat.is_spam()) {
maya_cat.spam() << "cvs dir " << dir->get_fullpath().to_os_generic() << endl;
maya_cat.spam() << "cvs path " << path.get_fullpath().to_os_generic() << endl;
}
MString result2;
if (maya_cat.is_debug()) {
string cmdStr = "pwd";
MString result3;
status = MGlobal::executeCommand(MString(cmdStr.c_str()), result3);
maya_cat.debug() << "result = " << result3.asChar() << "\n";
}
_exec_string.push_back("file -loadReference \"" + string(result.asChar()) + "\" -type \"mayaBinary\" -options \"v=0\" \"" + new_filename.to_os_generic() + "\";");
if (!_omit_ref) {
maya_cat.info() << "executing command: " << _exec_string[_curr_idx] << "\n";
status = MGlobal::executeCommand(MString(_exec_string[_curr_idx].c_str()));
if (status != MStatus::kSuccess) {
status.perror("loadReference failed");
}
}
_curr_idx++;
}
if (!_omit_tex) {
// Get all the shaders so we can determine the set of textures.
_shaders.clear();
collect_shaders();
int num_shaders = _shaders.get_num_shaders();
for (int i = 0; i < num_shaders; i++) {
MayaShader *shader = _shaders.get_shader(i);
for (size_t j = 0; j < shader->_all_maps.size(); j++) {
if (!extract_texture(*shader->_all_maps[j], dir)) {
return false;
}
}
}
}
// Now write out the Maya file.
if (!_maya->write(dest)) {
maya_cat.error()
<< "Cannot write " << dest << "\n";
return false;
}
for (ref_index = 0; ref_index < num_refs; ref_index++) {
if (1) { // we may want an option later to pull in all the referenced files
continue;
}
string lookup = refs[ref_index].asChar();
// for multiple reference of the same model. maya throws in a {#} at the
// end, ignore that
size_t dup = lookup.find('{');
if (dup != string::npos){
lookup.erase(dup);
}
Filename filename =
_path_replace->convert_path(Filename::from_os_specific(lookup));
maya_cat.info()
<< "External ref: " << filename << "\n";
// Now import the file
ExtraData ed;
ed._type = FT_maya;
CVSSourceTree::FilePath path = import(filename, &ed, _model_dir);
if (!path.is_valid()) {
exit(1);
}
}
return true;
}
/**
* Gets the texture out of the indicated color channel and copies it in,
* updating the channel with the new texture filename. Returns true on
* success, false on failure.
*/
bool MayaCopy::
extract_texture(MayaShaderColorDef &color_def, CVSSourceDirectory *dir) {
Filename texture_filename =
_path_replace->convert_path(color_def._texture_filename);
if (!texture_filename.exists()) {
nout << "*** Error: texture " << texture_filename
<< " does not exist.\n";
return false;
} else if (!texture_filename.is_regular_file()) {
nout << "*** Error: texture " << texture_filename
<< " is not a regular file.\n";
return false;
} else {
ExtraData ed;
ed._type = FT_texture;
CVSSourceTree::FilePath texture_path =
import(texture_filename, &ed, _map_dir);
if (!texture_path.is_valid()) {
return false;
}
// Update the texture reference to point to the new texture filename,
// relative to the maya file.
Filename new_filename = texture_path.get_rel_from(dir);
color_def.reset_maya_texture(new_filename);
}
return true;
}
/**
*
*/
bool MayaCopy::
copy_texture(const Filename &source, const Filename &dest,
CVSSourceDirectory *dir) {
if (!copy_binary_file(source, dest)) {
return false;
}
return true;
}
/**
* Recursively walks through the maya scene graph hierarchy, looking for
* shaders.
*/
bool MayaCopy::
collect_shaders() {
MStatus status;
MItDag dag_iterator(MItDag::kDepthFirst, MFn::kTransform, &status);
if (status != MStatus::kSuccess) {
status.perror("MItDag constructor");
return false;
}
// This while loop walks through the entire Maya hierarchy, one node at a
// time. Maya's MItDag object automatically performs a depth-first
// traversal of its scene graph.
bool all_ok = true;
while (!dag_iterator.isDone()) {
MDagPath dag_path;
status = dag_iterator.getPath(dag_path);
if (status != MStatus::kSuccess) {
status.perror("MItDag::getPath");
} else {
if (!collect_shader_for_node(dag_path)) {
all_ok = false;
}
}
dag_iterator.next();
}
if (!all_ok) {
nout << "Errors encountered in traversal.\n";
return false;
}
return true;
}
/**
* Gets the relevant shader on the current node, if it has one.
*/
bool MayaCopy::
collect_shader_for_node(const MDagPath &dag_path) {
MStatus status;
MFnDagNode dag_node(dag_path, &status);
if (status != MStatus::kSuccess) {
status.perror("MFnDagNode constructor");
return false;
}
if (dag_path.hasFn(MFn::kNurbsSurface)) {
MFnNurbsSurface surface(dag_path, &status);
if (status) {
_shaders.find_shader_for_node(surface.object(), false);
}
} else if (dag_path.hasFn(MFn::kMesh)) {
MFnMesh mesh(dag_path, &status);
if (status) {
// Meshes may have multiple different shaders.
MObjectArray shaders;
MIntArray poly_shader_indices;
status = mesh.getConnectedShaders(dag_path.instanceNumber(),
shaders, poly_shader_indices);
if (status) {
unsigned int num_shaders = shaders.length();
for (unsigned int shader_index = 0;
shader_index < num_shaders;
shader_index++) {
MObject engine = shaders[shader_index];
_shaders.find_shader_for_shading_engine(engine, false);
}
}
}
} else {
// Ignoring other kinds of node.
}
return true;
}
int main(int argc, char *argv[]) {
MayaCopy prog;
prog.parse_command_line(argc, argv);
prog.run();
return 0;
}

View File

@ -1,86 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file mayaCopy.h
* @author drose
* @date 2002-05-10
*/
#ifndef MAYACOPY_H
#define MAYACOPY_H
#include "pandatoolbase.h"
#include "cvsCopy.h"
#include "mayaApi.h"
#include "dSearchPath.h"
#include "pointerTo.h"
#include "pset.h"
#include "pre_maya_include.h"
#include <maya/MObject.h>
#include "post_maya_include.h"
#include "mayaShaders.h"
class MayaShader;
class MayaShaderColorDef;
/**
* A program to copy Maya .mb files into the cvs tree.
*/
class MayaCopy : public CVSCopy {
public:
MayaCopy();
void run();
protected:
virtual bool copy_file(const Filename &source, const Filename &dest,
CVSSourceDirectory *dir, void *extra_data,
bool new_file);
virtual std::string filter_filename(const std::string &source);
private:
enum FileType {
FT_maya,
FT_texture
};
class ExtraData {
public:
FileType _type;
MayaShader *_shader;
};
bool copy_maya_file(const Filename &source, const Filename &dest,
CVSSourceDirectory *dir);
bool extract_texture(MayaShaderColorDef &color_def, CVSSourceDirectory *dir);
bool copy_texture(const Filename &source, const Filename &dest,
CVSSourceDirectory *dir);
bool collect_shaders();
bool collect_shader_for_node(const MDagPath &dag_path);
bool _keep_ver;
bool _omit_tex;
bool _omit_ref;
int _curr_idx;
bool _maya_ascii;
/*
vector_string _replace_prefix;
*/
vector_string _exec_string;
PT(MayaApi) _maya;
MayaShaders _shaders;
};
#endif