//@copyright_begin // ================================================================ // Copyright Notice // Copyright (C) 1998-2004 by Joe Linoff // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // IN NO EVENT SHALL JOE LINOFF BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. // // Comments and suggestions are always welcome. // Please report bugs to http://ccdoc.sourceforge.net/ccdoc // ================================================================ //@copyright_end #include "switches.h" #include #include #ifndef CCDOC_CID #define CCDOC_CID "test" #endif #ifndef CCDOC_VERSION // This variable is automatically updated by release.pl. #define CCDOC_VERSION "v08r41 2004/09/29" #endif // ================================================================ // This static variable allows the header version // to be queried at runtime. // ================================================================ namespace { char ccdoc_rcsid[] = "$Id: switches.cc,v 1.24 2004/09/30 04:16:07 jlinoff Exp $"; } // ================================================================ // Constructor. // ================================================================ ccdoc::switches::switches(int argc,char** argv) { ccdoc_assert( argc ); ccdoc_assert( argv != 0 ); m_ok = true; m_help = false; m_program_name = argv[0]; m_verbose = false; m_verbose_format = true; m_index = false; m_default_root = "@root"; m_root = m_default_root; m_rootfile = ""; m_dospaths = false; m_jdsds = true; // Issue 0082 m_doxygen = true; // Issues 0162 and 0163 m_rptcfuns = false; // Issue 0133 m_rptcsd = true; // Issue 0026 m_rptcsi = 4; // Issue 0044 m_rptdpa = false; // Issue 0028 m_rptdpd = false; // Issue 0030 m_rptdpv = false; // Issue 0029 m_rptfwcf = false; // Issue 0045 m_rpthpc = true; // Issue 0026 m_rptim = true; m_rptmac = false; m_rptmac1 = false; // Issue 00153 m_rptpri = false; m_rptpro = false; m_rptpub = true; m_rptsci = true; // Issue 0072 m_rpttyp = true; m_rptun = true; m_rptsrc = false; // Report source info. string rptctcs = "iso-8859-1"; m_rptdefa = "unascribed"; // Issue 0063 m_rptdefasd = "automatically generated"; // Issue 0063 m_rptdefsd = "undocumented"; // Issue 0063 m_rptdefv = "unknown"; // Issue 0063 m_rptctcs = rptctcs; // Issue 0074 m_maxpathlen = 128; m_cdsm = true; m_tcms = false; // r33 - ignore template class methods m_rptmlcei = 32; // Issue 0159 m_rptmlcifi = 32; // Issue 0159 m_version = "ccdoc "; m_version += CCDOC_VERSION; m_version += " "; m_version += CCDOC_CID; bool report_args = false; bool version_flag = false; // Insert the definition for __ccdoc__ { string key = "__ccdoc__"; string value = "1"; m_defines.insert( make_pair(key,value) ); } // Process the switches. for(int i=0;i) not specified.\n"; s_log << " Type ccdoc -h for more information.\n"; s_log << "\n"; } } } // Make sure that the user didn't specify -meta and -rptctcs at // the same time. if( ok() ) { if( m_meta.size() && m_rptctcs != rptctcs ) { s_log.warning() << "The -meta and -rptctcs switches are mutually exclusive.\n" << "\tThe -rptctcs switch will be ignored.\n" << s_log.enable(); } } if( ok() ) { if( m_rptmac1 ) m_rptmac = true; } } // ================================================================ // Destructor. // ================================================================ ccdoc::switches::~switches() { } // ================================================================ // Get arg. // ================================================================ bool ccdoc::switches::get_arg(const char* sw, string& str, int& i, int argc, char** argv) { if( str == sw ) { if( ++i >= argc ) { s_log << "ERROR: Missing argument for switch '" << argv[i-1] << "'\n"; m_ok = false; return false; } str = argv[i]; return true; } return false; } // ================================================================ // Load a file. // ================================================================ void ccdoc::switches::load_file(const string& file) { if( file[0] == '-' ) { // The user might have specified an invalid // switch, warn them but then add it as a file. s_log.warning() << "Switch '" << file << "' is treated as a file.\n" << s_log.enable(); } // This is assumed to be a file. ifstream is(file.c_str()); if( !is ) { #if defined(_MSC_VER) // Issue 0007 // This only works for the MSVC version of the program. // Under DOS, this error may have occurred because the // user specified a wildcard. Try to convert the file to a list. string tmp; string cmd; int st; tmp = "ccdoc_msdos.tmp"; // Issue 0129 // Changed // cmd = "DIR /B /S /O:N " // tp // cmd = "DIR /B /O:N " // The /S switch was causing unwanted side effects. // // Issue 0180 // Changed // cmd = "DIR /B /O:N file" // to // cmd = "DIR /B /O:N \"file\" // The lack of quotes caused problems for directories // and files that had embedded spaces. //OLD: cmd = "DIR /B /O:N " + file + " > " + tmp + "\n"; cmd = "DIR /B /O:N \"" + file + "\" > " + tmp + "\n"; if( verbose() ) { s_log << cmd << "\n"; } st = system(cmd.c_str()); if( verbose() ) { s_log << "status = " << st << "\n"; } if( st == 0 ) { // Issue 0129: // "fix" the entries in the load file by pre-pending // the leading directory. I tried to do this by using // the /S switch but that didn't work because that // switch generates the long files names AND all files // in subdirectories. string prefix; size_t last = file.find_last_of("\\"); if( last != string::npos ) { prefix = file.substr(0,last+1); load_files(tmp,prefix.c_str()); } else { load_files(tmp); } cmd = "DEL " + tmp + "\n"; system(cmd.c_str()); return; } #endif s_log.warning() << "File '" << file << "' cannot be read so it will be ignored.\n" << s_log.enable(); } else { // Only add files that can be read. m_files.push_back( file ); } } // ================================================================ // Load a file that contains a list of files. // ================================================================ void ccdoc::switches::load_files(const string& file,const char* prefix) { // The user specified a list of files, // open it and load the files in the internal m_files // vector. ifstream is(file.c_str()); if( is.fail() || is.bad() ) { s_log.warning() << "Can't read -files " << file.c_str() << " so it will be ignored.\n" << s_log.enable(); } else { static char nbuf[65536]; string token; while( is.getline(nbuf,sizeof(nbuf)) ) { int nbuf_cmp = *nbuf; // eliminate compiler warning if( nbuf_cmp > 32 && nbuf_cmp < 128) { if( verbose() ) { s_log << "loading file " << nbuf << " ...\n"; } if( prefix ) { token = prefix; token += nbuf; m_files.push_back( token ); } else { m_files.push_back( nbuf ); } } } } } // ================================================================ // Put env // ================================================================ void ccdoc::switches::putenv( string& str ) const { // We need to keep a permanent copy of the environment // variables to be safe on different platforms. const unsigned MAX_ENVS = 32; static unsigned s_putenv_idx = 0; static char s_putenv[MAX_ENVS][4096]; ccdoc_assert( s_putenv_idx < MAX_ENVS ); ccdoc_assert( str.size() < 4096 ); char* putenv_string = s_putenv[ s_putenv_idx ]; strcpy( putenv_string, str.c_str() ); ::putenv( putenv_string ); s_putenv_idx++; } // ================================================================ // Load the defines map. // ================================================================ void ccdoc::switches::defines( defines_type& out ) const { for( defines_type::const_iterator i=m_defines.begin();i!=m_defines.end();++i) { out.insert( make_pair((*i).first,(*i).second) ); } } // ================================================================ // Load the undefines set. // ================================================================ void ccdoc::switches::undefines( undefines_type& out ) const { for( undefines_type::const_iterator i=m_undefines.begin();i!=m_undefines.end();++i) { out.insert( *i ); } }