| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| #include <precomp.h> |
| #include <adc_cl.hxx> |
| |
| |
| // NOT FULLY DEFINED SERVICES |
| #include <algorithm> |
| #include <cosv/x.hxx> |
| #include <cosv/file.hxx> |
| #include <cosv/tpl/tpltools.hxx> |
| #include <ary/ary.hxx> |
| #include <tools/tkpchars.hxx> |
| #include <adc_msg.hxx> |
| #include "adc_cmds.hxx" |
| #include "adc_cmd_parse.hxx" |
| #include "cmd_sincedata.hxx" |
| |
| |
| namespace autodoc |
| { |
| |
| CommandLine * CommandLine::pTheInstance_ = 0; |
| |
| const char * const C_sUserGuide = |
| "\n\n\n" |
| " General Use of Autodoc\n" |
| " ----------------------\n" |
| "\n" |
| " Example for C++:\n" |
| "\n" |
| " -html <OutputDirectory> -name \"UDK 3.x anything\" -lg c++\n" |
| " -p <ProjName> <ProjectRootDirectory>\n" |
| " -t <SourceDir_relativeToProjectRoot>\n" |
| "\n" |
| " There may be several projects specified by -p.\n" |
| "\n" |
| "\n" |
| " Example for IDL:\n" |
| "\n" |
| " -html <OutputDirectory> -name \"UDK 3.x anything\" -lg idl\n" |
| " -t <SourceDir1> <SourceDir2>\n" |
| "\n" |
| " For both languages, instead of or in addition to -t may be\n" |
| " used -d (no subdirectories) or -f (just one file). There can\n" |
| " be multiple arguments after each of these options (-t -d -f).\n" |
| "\n" |
| "\n" |
| " Replacing @since Tag Content\n" |
| " ----------------------------\n" |
| "\n" |
| " In both languages you can give a transformation file to replace\n" |
| " entries in @since tags by different entries.\n" |
| " This file is given by the option\n" |
| " -sincefile <TransformationFilePath>\n" |
| " This option has to appear between the -html and the -lg option.\n" |
| " Example:\n" |
| " -html <OutputDirectory> -sincefile replacesince.txt\n" |
| " -name \"UDK 3.x anything\" -lg idl -t <SourceDir>\n" |
| "\n" |
| "\n"; |
| |
| |
| #if 0 // FUTURE |
| "\n\n\n" |
| " Use of Autodoc\n" |
| " --------------\n" |
| "\n" |
| " Basics:\n" |
| "\n" |
| " Autodoc may perform different tasks.\n" |
| "\n" |
| " Possible tasks are\n" |
| " - parsing source code\n" |
| " - creating HTML-output.\n" |
| " On the command line each task starts with a specific\n" |
| " option:\n" |
| " '-parse' for parsing source code,\n" |
| " '-html' for creating HTML.\n" |
| " All command line options, related to one task, have to follow before\n" |
| " the starting option of the next task.\n" |
| "\n" |
| " Within the task '-parse', there may be defined different projects.\n" |
| " A project definition is started with '-p'.\n" |
| " All not project specific options within the task '-parse' have to\n" |
| " appear in front of the first '-p'.\n" |
| " There can be no project at all. Then all options, available for\n" |
| " projects, can be used like for one nameless default project, without using\n" |
| " '-p', but these options still have to appear behind all other\n" |
| " options of the task '-parse'.\n" |
| "\n" |
| "\n" |
| " Legend:\n" |
| "\n" |
| " <SomeText> Describes an argument.\n" |
| " 'SomeText' Within '...' is the literal value of an argument.\n" |
| " + There can be multiple arguments.\n" |
| " | Separator for alternative literal values of an argument.\n" |
| "\n" |
| "\n" |
| " Syntax:\n" |
| "\n" |
| " -parse\n" |
| " -name <RepositoryName>]\n" |
| " -lg 'c++'|'idl'\n" |
| " -extg <AdditonalExtensions>+\n" |
| " -docg 'usehtml'\n" |
| " -p <ProjectName> <ProjectRootDir>\n" |
| " -l 'c++'|'idl'\n" |
| " -ext <AdditonalExtensions>+\n" |
| " -doc 'usehtml'\n" |
| " -d <SourceDir_relative2ProjectRootDir_nosubdirs>+\n" |
| " -t <SourceTree_relative2ProjectRootDir>+\n" |
| " -f <SourceFile_relative2ProjectRootDir>+\n" |
| " -html <OutputDir>\n" |
| " -xlinks <Namespace> <ExternLinksRootDir>\n" |
| " -i <CommandFilePath>\n" |
| " -v <VerboseNr>\n" |
| "\n" |
| "\n" |
| " Detailed Options Description:\n" |
| "\n" |
| " Option Arguments\n" |
| " ----------------------------------------------------------\n" |
| "\n" |
| " -parse \n\n" |
| " Starts the task \"Parse source code\".\n" |
| " May be omitted, if it would be the first option on the\n" |
| " command line.\n" |
| "\n" |
| " -name <RepositoryName>\n\n" |
| " This name is used for naming the repository in\n" |
| " human readable output. In future it may be used also for\n" |
| " identifiing a repository in searches.\n" |
| "\n" |
| " -lg 'c++|'idl'\n\n" |
| " Identifies the programming language to be parsed.\n" |
| " 'c++': C++\n" |
| " Files with extensions '.h', '.hxx' are parsed.\n" |
| " 'idl': UNO-IDL\n" |
| " Files with extensions '.idl' are parsed.\n" |
| " Here the language is set globally for all projects.\n" |
| " A project can override this by using '-l'.\n" |
| "\n" |
| " -extg <.AdditionalExtension>+\n\n" |
| " Has to follow immediately behind '-lg'.\n" |
| " Specifies additional extensions, that will be recognised as\n" |
| " source code files of the previously specified programming\n" |
| " language. Each extension has to start with '.'.\n" |
| " It is possible to include extensionless files, too,\n" |
| " by the argument '.'\n" |
| " Here these extensions are set globally for all projects.\n" |
| " A project can override this by using '-l' and '-ext'.\n" |
| "\n" |
| " -docg 'html'|'nohtml'\n\n" |
| " Specifies the default for all comments in source code, so \n" |
| " that HTML-tags are interpreted as such or else treated as\n" |
| " regular text.\n" |
| " Without this option, the default is 'nohtml'.\n" |
| " Here the default is set globally for all projects.\n" |
| " A project can override this by using '-doc'.\n" |
| "\n" |
| " -p <ProjectName> <ProjectRootDirectory>\n\n" |
| " ProjectName is used in output as human readable identifier\n" |
| " for the project. ProjectRootDirectory is the path,\n" |
| " where the arguments of '-d', '-t' and '-f' are relative to.\n" |
| " This option can be omitted, then there is no project name\n" |
| " and all paths are relative to the current working directory.\n" |
| "\n" |
| " -l 'c++|'idl'\n\n" |
| " Overrides -lg and -extg for the current project, which is\n" |
| " specified by the last previous '-p'.\n" |
| " For details see at option '-lg'.\n" |
| "\n" |
| " -ext <.AdditionalExtension>+\n\n" |
| " Can be used only immediately behind '-l'.\n" |
| " Overrides -extg for the current project, which is\n" |
| " specified by the last previous '-p'.\n" |
| " For details see at option '-extg'.\n" |
| "\n" |
| " -doc 'html'|'nohtml'\n\n" |
| " Overrides -docg for the current project, which is\n" |
| " specified by the last previous '-p'.\n" |
| " For details see at option '-docg'.\n" |
| "\n" |
| " -d <SourceDir_relative2ProjectRootDir_nosubdirs>+\n\n" |
| " For the current project all files in the given\n" |
| " directories are parsed, which have valid extensions.\n" |
| " Subdirectories are NOT parsed.\n" |
| "\n" |
| " -t <SourceTree_relative2ProjectRootDir>+\n\n" |
| " For the current project all files in the given\n" |
| " directories AND its subdirectories are parsed, which\n" |
| " have valid extensions.\n" |
| "\n" |
| " -f <SourceFile_relative2ProjectRootDir>+\n\n" |
| " For the current project and language the given files\n" |
| " are parsed. It doesn't matter, if their extensions match\n" |
| " the valid extensions.\n" |
| "\n" |
| " -html <OutputRootDir>\n\n" |
| " Starts the task \"Create HTML output\".\n" |
| "\n" |
| " -xlinks <Namespace> <ExternLinksRootDir>\n\n" |
| " This option allows, to create links to external\n" |
| " HTML-documents.\n" |
| " For all source code objects (like classes or functions)\n" |
| " which belong in the given namespace, the given root\n" |
| " directory is used as a base for links to them.\n" |
| " Presently, this works only for C++-mappings of IDL-items.\n" |
| " The given namespace has to be absolute.\n" |
| "\n" |
| " -i <CommandFilePath>\n\n" |
| " This option is replaced by the contents of the given\n" |
| " file. The file has to be ASCII and each option\n" |
| " has to start in the first column of a new line.\n" |
| " So each valid line starts with a '-'.\n" |
| " Empty lines are allowed.\n" |
| " Comment lines have to start with '#'\n" |
| "\n" |
| " -v <VerboseNumber>\n\n" |
| " Show details during parsing:\n" |
| " 2 shows each parsed letter,\n" |
| " 4 shows stored objects.\n" |
| " 1 shows recognised tokens.\n" |
| " These bit-values can be combined.\n" |
| " This option suppresses errors, because of\n" |
| " missing output options (no '-html').\n"; |
| #endif // 0, FUTURE |
| |
| |
| CommandLine::CommandLine() |
| : nDebugStyle(0), |
| pSinceTransformator(new command::SinceTagTransformationData), |
| aCommands(), |
| bInitOk(false), |
| pCommand_CreateHtml(0), |
| pReposy( & ary::Repository::Create_() ), |
| bCpp(false), |
| bIdl(false) |
| { |
| csv_assert(pTheInstance_ == 0); |
| pTheInstance_ = this; |
| } |
| |
| CommandLine::~CommandLine() |
| { |
| csv::erase_container_of_heap_ptrs(aCommands); |
| pTheInstance_ = 0; |
| } |
| |
| int |
| CommandLine::Run() const |
| { |
| Cout() << "\nAutodoc version 2.2.5" |
| << "\n---------------------" |
| << "\n" << Endl(); |
| |
| bool |
| ok = true; |
| for ( CommandList::const_iterator it = aCommands.begin(); |
| ok AND it != aCommands.end(); |
| ++it ) |
| { |
| ok = (*it)->Run(); |
| } |
| |
| if (pCommand_CreateHtml != 0) |
| { |
| StreamStr aDiagnosticMessagesFile(700); |
| aDiagnosticMessagesFile |
| << pCommand_CreateHtml->OutputDir() |
| << csv::ploc::Delimiter() |
| << "Autodoc_DiagnosticMessages.txt"; |
| TheMessages().WriteFile(aDiagnosticMessagesFile.c_str()); |
| } |
| |
| return ok ? 0 : 1; |
| } |
| |
| CommandLine & |
| CommandLine::Get_() |
| { |
| csv_assert(pTheInstance_ != 0); |
| return *pTheInstance_; |
| } |
| |
| bool |
| CommandLine::DoesTransform_SinceTag() const |
| { |
| return pSinceTransformator->DoesTransform(); |
| } |
| |
| //bool |
| //CommandLine::Strip_SinceTagText( String & io_sSinceTagValue ) const |
| //{ |
| // return pSinceTransformator->StripSinceTagText(io_sSinceTagValue); |
| //} |
| |
| const String & |
| CommandLine::DisplayOf_SinceTagValue( const String & i_sVersionNumber ) const |
| { |
| return pSinceTransformator->DisplayOf(i_sVersionNumber); |
| } |
| |
| void |
| CommandLine::do_Init( int argc, |
| char * argv[] ) |
| { |
| try |
| { |
| bInitOk = false; |
| StringVector aParameters; |
| |
| char * * itpEnd = &argv[0] + argc; |
| for ( char * * itp = &argv[1]; itp != itpEnd; ++itp ) |
| { |
| if ( strncmp(*itp, "-I:", 3) != 0 ) |
| aParameters.push_back(String(*itp)); |
| else |
| load_IncludedCommands(aParameters, (*itp)+3); |
| } |
| |
| StringVector::const_iterator itEnd = aParameters.end(); |
| for ( StringVector::const_iterator it = aParameters.begin(); |
| it != itEnd; |
| ) |
| { |
| if ( *it == command::C_opt_Verbose ) |
| do_clVerbose(it,itEnd); |
| else if ( *it == command::C_opt_LangAll |
| OR *it == command::C_opt_Name |
| OR *it == command::C_opt_DevmanFile ) |
| do_clParse(it,itEnd); |
| else if (*it == command::C_opt_CreateHtml) |
| do_clCreateHtml(it,itEnd); |
| else if (*it == command::C_opt_SinceFile) |
| do_clSinceFile(it,itEnd); |
| else if (*it == command::C_opt_ExternNamespace) |
| { |
| sExternNamespace = *(++it); |
| ++it; |
| if ( strncmp(sExternNamespace.c_str(), "::", 2) != 0) |
| { |
| throw command::X_CommandLine( |
| "-extnsp needs an absolute qualified namespace, starting with \"::\"." |
| ); |
| } |
| } |
| else if (*it == command::C_opt_ExternRoot) |
| { |
| ++it; |
| StreamLock sl(1000); |
| if ( csv::compare(*it, 0, "http://", 7) != 0 ) |
| { |
| sl() << "http://" << *it; |
| } |
| if ( *(sl().end()-1) != '/') |
| sl() << '/'; |
| sExternRoot = sl().c_str(); |
| |
| ++it; |
| } |
| // else if (*it == command::C_opt_CreateXml) |
| // do_clCreateXml(it,itEnd); |
| // else if (command::C_opt_Load) |
| // do_clLoad(it,itEnd); |
| // else if (*it == command::C_opt_Save) |
| // do_clSave(it,itEnd); |
| else if (*it == "-h" OR *it == "-?" OR *it == "?") |
| // Leads to displaying help, because bInitOk stays on false. |
| return; |
| else if ( *it == command::C_opt_Parse ) |
| // Only for backwards compatibility. |
| // Just ignore "-parse". |
| ++it; |
| else |
| { |
| StreamLock sl(200); |
| throw command::X_CommandLine( |
| sl() << "Unknown commandline option \"" |
| << *it |
| << "\"." |
| << c_str ); |
| } |
| } // end for |
| sort_Commands(); |
| |
| bInitOk = true; |
| |
| } // end try |
| catch ( command::X_CommandLine & xxx ) |
| { |
| xxx.Report( Cerr() ); |
| } |
| catch ( csv::Exception & xxx ) |
| { |
| xxx.GetInfo( Cerr() ); |
| } |
| } |
| |
| void |
| CommandLine::do_PrintUse() const |
| { |
| Cout() << C_sUserGuide << Endl(); |
| } |
| |
| bool |
| CommandLine::inq_CheckParameters() const |
| { |
| if (NOT bInitOk OR aCommands.size() == 0) |
| return false; |
| return true; |
| } |
| |
| void |
| CommandLine::load_IncludedCommands( StringVector & out, |
| const char * i_filePath ) |
| { |
| CharacterSource |
| aIncludedCommands; |
| csv::File |
| aFile(i_filePath, csv::CFM_READ); |
| if (NOT aFile.open()) |
| { |
| Cerr() << "Command include file \"" |
| << i_filePath |
| << "\" not found." |
| << Endl(); |
| throw command::X_CommandLine("Invalid file in option -I:<command-file>."); |
| } |
| aIncludedCommands.LoadText(aFile); |
| aFile.close(); |
| |
| bool bInToken = false; |
| StreamLock aTransmit(200); |
| for ( ; NOT aIncludedCommands.IsFinished(); aIncludedCommands.MoveOn() ) |
| { |
| if (bInToken) |
| { |
| if (aIncludedCommands.CurChar() <= 32) |
| { |
| const char * |
| pToken = aIncludedCommands.CutToken(); |
| bInToken = false; |
| |
| if ( strncmp(pToken, "-I:", 3) != 0 ) |
| { |
| aTransmit().seekp(0); |
| aTransmit() << pToken; |
| aTransmit().replace_all('\\', *csv::ploc::Delimiter()); |
| aTransmit().replace_all('/', *csv::ploc::Delimiter()); |
| out.push_back(String(aTransmit().c_str())); |
| } |
| else |
| load_IncludedCommands(out, pToken+3); |
| } |
| } |
| else |
| { |
| if (aIncludedCommands.CurChar() > 32) |
| { |
| aIncludedCommands.CutToken(); |
| bInToken = true; |
| } |
| } // endif (bInToken) else |
| |
| } // end while() |
| } |
| |
| namespace |
| { |
| inline int |
| v_nr(StringVector::const_iterator it) |
| { |
| return int( *(*it).c_str() ) - int('0'); |
| } |
| } // anonymous namespace |
| |
| void |
| CommandLine::do_clVerbose( opt_iter & it, |
| opt_iter itEnd ) |
| { |
| ++it; |
| if ( it == itEnd ? true : v_nr(it) < 0 OR v_nr(it) > 7 ) |
| throw command::X_CommandLine( "Missing or invalid number in -v option." ); |
| nDebugStyle = v_nr(it); |
| ++it; |
| } |
| |
| void |
| CommandLine::do_clParse( opt_iter & it, |
| opt_iter itEnd ) |
| { |
| command::Command * |
| pCmd_Parse = new command::Parse; |
| pCmd_Parse->Init(it, itEnd); |
| aCommands.push_back(pCmd_Parse); |
| } |
| |
| void |
| CommandLine::do_clCreateHtml( opt_iter & it, |
| opt_iter itEnd ) |
| { |
| pCommand_CreateHtml = new command::CreateHtml; |
| pCommand_CreateHtml->Init(it, itEnd); |
| aCommands.push_back(pCommand_CreateHtml); |
| } |
| |
| void |
| CommandLine::do_clSinceFile( opt_iter & it, |
| opt_iter itEnd ) |
| { |
| pSinceTransformator->Init(it, itEnd); |
| } |
| |
| |
| namespace |
| { |
| |
| struct Less_RunningRank |
| { |
| bool operator()( |
| const command::Command * const & |
| i1, |
| const command::Command * const & |
| i2 ) const |
| { return i1->RunningRank() < i2->RunningRank(); } |
| }; |
| |
| } // anonymous namespace |
| |
| |
| |
| void |
| CommandLine::sort_Commands() |
| { |
| std::sort( aCommands.begin(), |
| aCommands.end(), |
| Less_RunningRank() ); |
| } |
| |
| } // namespace autodoc |