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