1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 #include <precomp.h> 23 #include <adc_cl.hxx> 24 25 26 // NOT FULLY DEFINED SERVICES 27 #include <algorithm> 28 #include <cosv/x.hxx> 29 #include <cosv/file.hxx> 30 #include <cosv/tpl/tpltools.hxx> 31 #include <ary/ary.hxx> 32 #include <tools/tkpchars.hxx> 33 #include <adc_msg.hxx> 34 #include "adc_cmds.hxx" 35 #include "adc_cmd_parse.hxx" 36 #include "cmd_sincedata.hxx" 37 38 39 namespace autodoc 40 { 41 42 CommandLine * CommandLine::pTheInstance_ = 0; 43 44 const char * const C_sUserGuide = 45 "\n\n\n" 46 " General Use of Autodoc\n" 47 " ----------------------\n" 48 "\n" 49 " Example for C++:\n" 50 "\n" 51 " -html <OutputDirectory> -name \"UDK 3.x anything\" -lg c++\n" 52 " -p <ProjName> <ProjectRootDirectory>\n" 53 " -t <SourceDir_relativeToProjectRoot>\n" 54 "\n" 55 " There may be several projects specified by -p.\n" 56 "\n" 57 "\n" 58 " Example for IDL:\n" 59 "\n" 60 " -html <OutputDirectory> -name \"UDK 3.x anything\" -lg idl\n" 61 " -t <SourceDir1> <SourceDir2>\n" 62 "\n" 63 " For both languages, instead of or in addition to -t may be\n" 64 " used -d (no subdirectories) or -f (just one file). There can\n" 65 " be multiple arguments after each of these options (-t -d -f).\n" 66 "\n" 67 "\n" 68 " Replacing @since Tag Content\n" 69 " ----------------------------\n" 70 "\n" 71 " In both languages you can give a transformation file to replace\n" 72 " entries in @since tags by different entries.\n" 73 " This file is given by the option\n" 74 " -sincefile <TransformationFilePath>\n" 75 " This option has to appear between the -html and the -lg option.\n" 76 " Example:\n" 77 " -html <OutputDirectory> -sincefile replacesince.txt\n" 78 " -name \"UDK 3.x anything\" -lg idl -t <SourceDir>\n" 79 "\n" 80 "\n"; 81 82 83 #if 0 // FUTURE 84 "\n\n\n" 85 " Use of Autodoc\n" 86 " --------------\n" 87 "\n" 88 " Basics:\n" 89 "\n" 90 " Autodoc may perform different tasks.\n" 91 "\n" 92 " Possible tasks are\n" 93 " - parsing source code\n" 94 " - creating HTML-output.\n" 95 " On the command line each task starts with a specific\n" 96 " option:\n" 97 " '-parse' for parsing source code,\n" 98 " '-html' for creating HTML.\n" 99 " All command line options, related to one task, have to follow before\n" 100 " the starting option of the next task.\n" 101 "\n" 102 " Within the task '-parse', there may be defined different projects.\n" 103 " A project definition is started with '-p'.\n" 104 " All not project specific options within the task '-parse' have to\n" 105 " appear in front of the first '-p'.\n" 106 " There can be no project at all. Then all options, available for\n" 107 " projects, can be used like for one nameless default project, without using\n" 108 " '-p', but these options still have to appear behind all other\n" 109 " options of the task '-parse'.\n" 110 "\n" 111 "\n" 112 " Legend:\n" 113 "\n" 114 " <SomeText> Describes an argument.\n" 115 " 'SomeText' Within '...' is the literal value of an argument.\n" 116 " + There can be multiple arguments.\n" 117 " | Separator for alternative literal values of an argument.\n" 118 "\n" 119 "\n" 120 " Syntax:\n" 121 "\n" 122 " -parse\n" 123 " -name <RepositoryName>]\n" 124 " -lg 'c++'|'idl'\n" 125 " -extg <AdditonalExtensions>+\n" 126 " -docg 'usehtml'\n" 127 " -p <ProjectName> <ProjectRootDir>\n" 128 " -l 'c++'|'idl'\n" 129 " -ext <AdditonalExtensions>+\n" 130 " -doc 'usehtml'\n" 131 " -d <SourceDir_relative2ProjectRootDir_nosubdirs>+\n" 132 " -t <SourceTree_relative2ProjectRootDir>+\n" 133 " -f <SourceFile_relative2ProjectRootDir>+\n" 134 " -html <OutputDir>\n" 135 " -xlinks <Namespace> <ExternLinksRootDir>\n" 136 " -i <CommandFilePath>\n" 137 " -v <VerboseNr>\n" 138 "\n" 139 "\n" 140 " Detailed Options Description:\n" 141 "\n" 142 " Option Arguments\n" 143 " ----------------------------------------------------------\n" 144 "\n" 145 " -parse \n\n" 146 " Starts the task \"Parse source code\".\n" 147 " May be omitted, if it would be the first option on the\n" 148 " command line.\n" 149 "\n" 150 " -name <RepositoryName>\n\n" 151 " This name is used for naming the repository in\n" 152 " human readable output. In future it may be used also for\n" 153 " identifiing a repository in searches.\n" 154 "\n" 155 " -lg 'c++|'idl'\n\n" 156 " Identifies the programming language to be parsed.\n" 157 " 'c++': C++\n" 158 " Files with extensions '.h', '.hxx' are parsed.\n" 159 " 'idl': UNO-IDL\n" 160 " Files with extensions '.idl' are parsed.\n" 161 " Here the language is set globally for all projects.\n" 162 " A project can override this by using '-l'.\n" 163 "\n" 164 " -extg <.AdditionalExtension>+\n\n" 165 " Has to follow immediately behind '-lg'.\n" 166 " Specifies additional extensions, that will be recognised as\n" 167 " source code files of the previously specified programming\n" 168 " language. Each extension has to start with '.'.\n" 169 " It is possible to include extensionless files, too,\n" 170 " by the argument '.'\n" 171 " Here these extensions are set globally for all projects.\n" 172 " A project can override this by using '-l' and '-ext'.\n" 173 "\n" 174 " -docg 'html'|'nohtml'\n\n" 175 " Specifies the default for all comments in source code, so \n" 176 " that HTML-tags are interpreted as such or else treated as\n" 177 " regular text.\n" 178 " Without this option, the default is 'nohtml'.\n" 179 " Here the default is set globally for all projects.\n" 180 " A project can override this by using '-doc'.\n" 181 "\n" 182 " -p <ProjectName> <ProjectRootDirectory>\n\n" 183 " ProjectName is used in output as human readable identifier\n" 184 " for the project. ProjectRootDirectory is the path,\n" 185 " where the arguments of '-d', '-t' and '-f' are relative to.\n" 186 " This option can be omitted, then there is no project name\n" 187 " and all paths are relative to the current working directory.\n" 188 "\n" 189 " -l 'c++|'idl'\n\n" 190 " Overrides -lg and -extg for the current project, which is\n" 191 " specified by the last previous '-p'.\n" 192 " For details see at option '-lg'.\n" 193 "\n" 194 " -ext <.AdditionalExtension>+\n\n" 195 " Can be used only immediately behind '-l'.\n" 196 " Overrides -extg for the current project, which is\n" 197 " specified by the last previous '-p'.\n" 198 " For details see at option '-extg'.\n" 199 "\n" 200 " -doc 'html'|'nohtml'\n\n" 201 " Overrides -docg for the current project, which is\n" 202 " specified by the last previous '-p'.\n" 203 " For details see at option '-docg'.\n" 204 "\n" 205 " -d <SourceDir_relative2ProjectRootDir_nosubdirs>+\n\n" 206 " For the current project all files in the given\n" 207 " directories are parsed, which have valid extensions.\n" 208 " Subdirectories are NOT parsed.\n" 209 "\n" 210 " -t <SourceTree_relative2ProjectRootDir>+\n\n" 211 " For the current project all files in the given\n" 212 " directories AND its subdirectories are parsed, which\n" 213 " have valid extensions.\n" 214 "\n" 215 " -f <SourceFile_relative2ProjectRootDir>+\n\n" 216 " For the current project and language the given files\n" 217 " are parsed. It doesn't matter, if their extensions match\n" 218 " the valid extensions.\n" 219 "\n" 220 " -html <OutputRootDir>\n\n" 221 " Starts the task \"Create HTML output\".\n" 222 "\n" 223 " -xlinks <Namespace> <ExternLinksRootDir>\n\n" 224 " This option allows, to create links to external\n" 225 " HTML-documents.\n" 226 " For all source code objects (like classes or functions)\n" 227 " which belong in the given namespace, the given root\n" 228 " directory is used as a base for links to them.\n" 229 " Presently, this works only for C++-mappings of IDL-items.\n" 230 " The given namespace has to be absolute.\n" 231 "\n" 232 " -i <CommandFilePath>\n\n" 233 " This option is replaced by the contents of the given\n" 234 " file. The file has to be ASCII and each option\n" 235 " has to start in the first column of a new line.\n" 236 " So each valid line starts with a '-'.\n" 237 " Empty lines are allowed.\n" 238 " Comment lines have to start with '#'\n" 239 "\n" 240 " -v <VerboseNumber>\n\n" 241 " Show details during parsing:\n" 242 " 2 shows each parsed letter,\n" 243 " 4 shows stored objects.\n" 244 " 1 shows recognised tokens.\n" 245 " These bit-values can be combined.\n" 246 " This option suppresses errors, because of\n" 247 " missing output options (no '-html').\n"; 248 #endif // 0, FUTURE 249 250 251 CommandLine::CommandLine() 252 : nDebugStyle(0), 253 pSinceTransformator(new command::SinceTagTransformationData), 254 aCommands(), 255 bInitOk(false), 256 pCommand_CreateHtml(0), 257 pReposy( & ary::Repository::Create_() ), 258 bCpp(false), 259 bIdl(false) 260 { 261 csv_assert(pTheInstance_ == 0); 262 pTheInstance_ = this; 263 } 264 265 CommandLine::~CommandLine() 266 { 267 csv::erase_container_of_heap_ptrs(aCommands); 268 pTheInstance_ = 0; 269 } 270 271 int 272 CommandLine::Run() const 273 { 274 Cout() << "\nAutodoc version 2.2.5" 275 << "\n---------------------" 276 << "\n" << Endl(); 277 278 bool 279 ok = true; 280 for ( CommandList::const_iterator it = aCommands.begin(); 281 ok AND it != aCommands.end(); 282 ++it ) 283 { 284 ok = (*it)->Run(); 285 } 286 287 if (pCommand_CreateHtml != 0) 288 { 289 StreamStr aDiagnosticMessagesFile(700); 290 aDiagnosticMessagesFile 291 << pCommand_CreateHtml->OutputDir() 292 << csv::ploc::Delimiter() 293 << "Autodoc_DiagnosticMessages.txt"; 294 TheMessages().WriteFile(aDiagnosticMessagesFile.c_str()); 295 } 296 297 return ok ? 0 : 1; 298 } 299 300 CommandLine & 301 CommandLine::Get_() 302 { 303 csv_assert(pTheInstance_ != 0); 304 return *pTheInstance_; 305 } 306 307 bool 308 CommandLine::DoesTransform_SinceTag() const 309 { 310 return pSinceTransformator->DoesTransform(); 311 } 312 313 //bool 314 //CommandLine::Strip_SinceTagText( String & io_sSinceTagValue ) const 315 //{ 316 // return pSinceTransformator->StripSinceTagText(io_sSinceTagValue); 317 //} 318 319 const String & 320 CommandLine::DisplayOf_SinceTagValue( const String & i_sVersionNumber ) const 321 { 322 return pSinceTransformator->DisplayOf(i_sVersionNumber); 323 } 324 325 void 326 CommandLine::do_Init( int argc, 327 char * argv[] ) 328 { 329 try 330 { 331 bInitOk = false; 332 StringVector aParameters; 333 334 char * * itpEnd = &argv[0] + argc; 335 for ( char * * itp = &argv[1]; itp != itpEnd; ++itp ) 336 { 337 if ( strncmp(*itp, "-I:", 3) != 0 ) 338 aParameters.push_back(String(*itp)); 339 else 340 load_IncludedCommands(aParameters, (*itp)+3); 341 } 342 343 StringVector::const_iterator itEnd = aParameters.end(); 344 for ( StringVector::const_iterator it = aParameters.begin(); 345 it != itEnd; 346 ) 347 { 348 if ( *it == command::C_opt_Verbose ) 349 do_clVerbose(it,itEnd); 350 else if ( *it == command::C_opt_LangAll 351 OR *it == command::C_opt_Name 352 OR *it == command::C_opt_DevmanFile ) 353 do_clParse(it,itEnd); 354 else if (*it == command::C_opt_CreateHtml) 355 do_clCreateHtml(it,itEnd); 356 else if (*it == command::C_opt_SinceFile) 357 do_clSinceFile(it,itEnd); 358 else if (*it == command::C_opt_ExternNamespace) 359 { 360 sExternNamespace = *(++it); 361 ++it; 362 if ( strncmp(sExternNamespace.c_str(), "::", 2) != 0) 363 { 364 throw command::X_CommandLine( 365 "-extnsp needs an absolute qualified namespace, starting with \"::\"." 366 ); 367 } 368 } 369 else if (*it == command::C_opt_ExternRoot) 370 { 371 ++it; 372 StreamLock sl(1000); 373 if ( csv::compare(*it, 0, "http://", 7) != 0 ) 374 { 375 sl() << "http://" << *it; 376 } 377 if ( *(sl().end()-1) != '/') 378 sl() << '/'; 379 sExternRoot = sl().c_str(); 380 381 ++it; 382 } 383 // else if (*it == command::C_opt_CreateXml) 384 // do_clCreateXml(it,itEnd); 385 // else if (command::C_opt_Load) 386 // do_clLoad(it,itEnd); 387 // else if (*it == command::C_opt_Save) 388 // do_clSave(it,itEnd); 389 else if (*it == "-h" OR *it == "-?" OR *it == "?") 390 // Leads to displaying help, because bInitOk stays on false. 391 return; 392 else if ( *it == command::C_opt_Parse ) 393 // Only for backwards compatibility. 394 // Just ignore "-parse". 395 ++it; 396 else 397 { 398 StreamLock sl(200); 399 throw command::X_CommandLine( 400 sl() << "Unknown commandline option \"" 401 << *it 402 << "\"." 403 << c_str ); 404 } 405 } // end for 406 sort_Commands(); 407 408 bInitOk = true; 409 410 } // end try 411 catch ( command::X_CommandLine & xxx ) 412 { 413 xxx.Report( Cerr() ); 414 } 415 catch ( csv::Exception & xxx ) 416 { 417 xxx.GetInfo( Cerr() ); 418 } 419 } 420 421 void 422 CommandLine::do_PrintUse() const 423 { 424 Cout() << C_sUserGuide << Endl(); 425 } 426 427 bool 428 CommandLine::inq_CheckParameters() const 429 { 430 if (NOT bInitOk OR aCommands.size() == 0) 431 return false; 432 return true; 433 } 434 435 void 436 CommandLine::load_IncludedCommands( StringVector & out, 437 const char * i_filePath ) 438 { 439 CharacterSource 440 aIncludedCommands; 441 csv::File 442 aFile(i_filePath, csv::CFM_READ); 443 if (NOT aFile.open()) 444 { 445 Cerr() << "Command include file \"" 446 << i_filePath 447 << "\" not found." 448 << Endl(); 449 throw command::X_CommandLine("Invalid file in option -I:<command-file>."); 450 } 451 aIncludedCommands.LoadText(aFile); 452 aFile.close(); 453 454 bool bInToken = false; 455 StreamLock aTransmit(200); 456 for ( ; NOT aIncludedCommands.IsFinished(); aIncludedCommands.MoveOn() ) 457 { 458 if (bInToken) 459 { 460 if (aIncludedCommands.CurChar() <= 32) 461 { 462 const char * 463 pToken = aIncludedCommands.CutToken(); 464 bInToken = false; 465 466 if ( strncmp(pToken, "-I:", 3) != 0 ) 467 { 468 aTransmit().seekp(0); 469 aTransmit() << pToken; 470 aTransmit().replace_all('\\', *csv::ploc::Delimiter()); 471 aTransmit().replace_all('/', *csv::ploc::Delimiter()); 472 out.push_back(String(aTransmit().c_str())); 473 } 474 else 475 load_IncludedCommands(out, pToken+3); 476 } 477 } 478 else 479 { 480 if (aIncludedCommands.CurChar() > 32) 481 { 482 aIncludedCommands.CutToken(); 483 bInToken = true; 484 } 485 } // endif (bInToken) else 486 487 } // end while() 488 } 489 490 namespace 491 { 492 inline int 493 v_nr(StringVector::const_iterator it) 494 { 495 return int( *(*it).c_str() ) - int('0'); 496 } 497 } // anonymous namespace 498 499 void 500 CommandLine::do_clVerbose( opt_iter & it, 501 opt_iter itEnd ) 502 { 503 ++it; 504 if ( it == itEnd ? true : v_nr(it) < 0 OR v_nr(it) > 7 ) 505 throw command::X_CommandLine( "Missing or invalid number in -v option." ); 506 nDebugStyle = v_nr(it); 507 ++it; 508 } 509 510 void 511 CommandLine::do_clParse( opt_iter & it, 512 opt_iter itEnd ) 513 { 514 command::Command * 515 pCmd_Parse = new command::Parse; 516 pCmd_Parse->Init(it, itEnd); 517 aCommands.push_back(pCmd_Parse); 518 } 519 520 void 521 CommandLine::do_clCreateHtml( opt_iter & it, 522 opt_iter itEnd ) 523 { 524 pCommand_CreateHtml = new command::CreateHtml; 525 pCommand_CreateHtml->Init(it, itEnd); 526 aCommands.push_back(pCommand_CreateHtml); 527 } 528 529 void 530 CommandLine::do_clSinceFile( opt_iter & it, 531 opt_iter itEnd ) 532 { 533 pSinceTransformator->Init(it, itEnd); 534 } 535 536 537 namespace 538 { 539 540 struct Less_RunningRank 541 { 542 bool operator()( 543 const command::Command * const & 544 i1, 545 const command::Command * const & 546 i2 ) const 547 { return i1->RunningRank() < i2->RunningRank(); } 548 }; 549 550 } // anonymous namespace 551 552 553 554 void 555 CommandLine::sort_Commands() 556 { 557 std::sort( aCommands.begin(), 558 aCommands.end(), 559 Less_RunningRank() ); 560 } 561 562 } // namespace autodoc 563