1(* $Id: oo2c.Mod,v 1.74 2004/11/24 03:57:57 sgreenhill Exp $ *) 2MODULE oo2c; 3(* Main module for the Oberon-2 to C translator. 4 Copyright (C) 2002-2004 Michael van Acken 5 6 This file is part of OOC. 7 8 OOC is free software; you can redistribute it and/or modify it 9 under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 2 of the License, or 11 (at your option) any later version. 12 13 OOC is distributed in the hope that it will be useful, but WITHOUT 14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 16 License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with OOC. If not, write to the Free Software Foundation, 59 20 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 21*) 22 23IMPORT 24 IO:StdChannels, Out, Err, Object, URI, URI:Scheme:File, CfgData := Config, 25 ADT:StringBuffer, IO, OS:ProcessManagement, OS:Path, OS:Files, 26 Config:Section:Options, 27 OOC:Logger, OOC:Config, OOC:Config:CCompiler, OOC:Package, 28 OOC:SymbolTable:Builder, OOC:Config:StdPragmas, OOC:Error, 29 Rep := OOC:Repository, OOC:Repository:FileSystem, OOC:Make, OOC:SSA:Stats; 30 31 32CONST 33 buildPackage = -1; 34 installPackage = -2; 35 uninstallPackage = -3; 36 updateRepository = -4; 37 getOption = -5; 38 buildPackageDoc = -6; 39 packageInstalled = -7; 40 listPackages = -8; 41 42VAR 43 cfgErrList, errList: Error.List; 44 i: LONGINT; 45 arg: STRING; 46 mode: SHORTINT; 47 command, forceUpdate, listUses, useStderr, writeStats, 48 verbose, errorStyle, showHelp, showVersion: Options.Option; 49 makeRules: Make.Rules; 50 rep: Rep.Repository; 51 r: Package.Repository; 52 pkg, pkgInfo: Package.Package; 53 ok, forceUpdateRepository, doInstall: BOOLEAN; 54 option: Options.Option; 55 module: Rep.Module; 56 57PROCEDURE NewConfig; 58 BEGIN 59 command := Config.AddOption("command", CfgData.NewIntegerVar(0)); 60 forceUpdate := Config.AddOption("forceUpdate", CfgData.NewBooleanVar(FALSE)); 61 listUses := Config.AddOption("listUses", CfgData.NewStringVar("")); 62 useStderr := Config.AddOption("useStderr", CfgData.NewBooleanVar(FALSE)); 63 writeStats := Config.AddOption("writeStats", CfgData.NewBooleanVar(FALSE)); 64 verbose := Config.AddOption("verbose", CfgData.NewBooleanVar(FALSE)); 65 errorStyle := Config.AddOption("errorStyle", 66 CfgData.NewStringVar("file:line:column")); 67 showHelp := Config.AddOption("showHelp", CfgData.NewBooleanVar(FALSE)); 68 showVersion := Config.AddOption("showVersion", CfgData.NewBooleanVar(FALSE)); 69 70 Config.AddRepositoryListEnv(); 71 Config.AddCmdLine ("--repository,-r", 72 "<repositories><file-system>$1</file-system></repositories>"); 73 Config.AddCmdLine ("--make,-M", 74 "<options><set name='command'>1</set></options>"); 75 Config.AddCmdLine ("--build-package", 76 "<options><set name='command'>2</set></options>"); 77 Config.AddCmdLine ("--install-package", 78 "<options><set name='command'>3</set></options>"); 79 Config.AddCmdLine ("--uninstall-package", 80 "<options><set name='command'>4</set></options>"); 81 Config.AddCmdLine ("--update-repository", 82 "<options><set name='command'>5</set></options>"); 83 Config.AddCmdLine ("--get-option", 84 "<options><set name='command'>6</set></options>"); 85 Config.AddCmdLine ("--build-pkg-doc", 86 "<options><set name='command'>7</set></options>"); 87 Config.AddCmdLine ("--package-installed", 88 "<options><set name='command'>8</set></options>"); 89 Config.AddCmdLine ("--list-packages", 90 "<options><set name='command'>9</set></options>"); 91 92 Config.AddCmdLine ("-h,--help", 93 "<options><set name='showHelp'>TRUE</set></options>"); 94 Config.AddCmdLine ("--version", 95 "<options><set name='showVersion'>TRUE</set></options>"); 96 Config.AddCmdLine ("--no-rtc", 97 "<pragmas>"+ 98 " <set name='Assertions'>FALSE</set>"+ 99 " <set name='IndexCheck'>FALSE</set>"+ 100 " <set name='DerefCheck'>FALSE</set>"+ 101 " <set name='OverflowCheck'>FALSE</set>"+ 102 " <set name='CaseSelectCheck'>FALSE</set>"+ 103 " <set name='FunctResult'>FALSE</set>"+ 104 " <set name='TypeGuard'>FALSE</set>"+ 105 "</pragmas>"); 106 Config.AddCmdLine ("--verbose,-v", 107 "<options><set name='verbose'>TRUE</set></options>"); 108 Config.AddCmdLine ("--warnings,-w", ""); (* ignored for now *) 109 110 Config.AddCmdLine ("-A,--all", 111 "<options><set name='forceUpdate'>TRUE</set></options>"); 112 Config.AddCmdLine ("--uses", 113 "<options>"+ 114 " <set name='listUses'>$1</set>"+ 115 " <set name='command'>1</set>"+ (* --make *) 116 "</options>"); 117 Config.AddCmdLine ("--error-style", 118 "<options><set name='errorStyle'>$1</set></options>"); 119 Config.AddCmdLine ("--use-stderr", 120 "<options><set name='useStderr'>TRUE</set></options>"); 121 Config.AddCmdLine ("--stats", 122 "<options><set name='writeStats'>TRUE</set></options>"); 123 CCompiler.RegisterConfig; 124 END NewConfig; 125 126PROCEDURE GetModule (moduleName: STRING): Rep.Module; 127 VAR 128 m: Rep.Module; 129 chars: Object.CharsLatin1; 130 str: Object.String8; 131 BEGIN 132 str := moduleName.ToString8("?"); 133 chars := str.CharsLatin1(); 134 m := Config.repositories.GetModule(chars^); 135 IF (m = NIL) THEN 136 Err.String ("Error: Cannot locate module "); 137 Err.String (chars^); 138 Err.Ln; 139 HALT (1) 140 END; 141 RETURN m; 142 END GetModule; 143 144PROCEDURE BuildPackage(pkg: Package.Package; rep: Rep.Repository; 145 install: BOOLEAN): BOOLEAN 146RAISES IO.Error; 147 VAR 148 ok: BOOLEAN; 149 i: LONGINT; 150 lib: Package.Library; 151 exec: Package.Executable; 152 normSet: Package.FileSet; 153 module: Rep.Module; 154 installObjects: BOOLEAN; 155 156 PROCEDURE InstallDirectory(prefix, path: STRING): BOOLEAN; 157 VAR 158 cmd: STRING; 159 BEGIN 160 IF (prefix.length # 0) THEN 161 path := prefix+"/"+path; 162 END; 163 164 IF Files.Exists(path) THEN 165 (* path name exists (although it may be a non-directory *) 166 RETURN TRUE; 167 ELSE 168 cmd := CCompiler.InstallDirectoryCmd(path); 169 Logger.ShellCommand(cmd); 170 RETURN (ProcessManagement.system(cmd) = 0); 171 END; 172 END InstallDirectory; 173 174 PROCEDURE InstallLibrary(module: Rep.Module; makeRules: Make.Rules): BOOLEAN; 175 (* Note: This procedure adds symbol files to the package's 176 @ofield{pkg.fileSet}. 177 178 pre: Full update has been done for the library's main module. *) 179 VAR 180 uri: URI.URI; 181 cmd: STRING; 182 m: Rep.Module; 183 i: LONGINT; 184 installObjects: BOOLEAN; 185 BEGIN 186 installObjects := ~CCompiler.HaveLibtool(); 187 188 (* For every symbol file, its doc string file, and the header file, add 189 an entry to the package's file list. The source and destination name 190 is the file name relative to the repository. Upon installation, the 191 former is interpreted relative to the providing repository, and the 192 latter relative to the installation directory. *) 193 FOR i := 0 TO LEN(makeRules.imports^)-1 DO 194 m := makeRules.imports[i]; 195 196 IF (m.origin = module.origin) THEN 197 IF installObjects & ~m.ifData.NoObjectFile() THEN 198 pkg.fileSet.Append(Package.NewFile(m.origin.GetLocalPath(m, Rep.modObjectFile), NIL)); 199 END; 200 201 pkg.fileSet.Append(Package.NewFile(m.origin.GetLocalPath(m, Rep.modSymbolFile), NIL)); 202 pkg.fileSet.Append(Package.NewFile(m.origin.GetLocalPath(m, Rep.modSymbolFileDoc), NIL)); 203 pkg.fileSet.Append(Package.NewFile(m.origin.GetLocalPath(m, Rep.modHeaderFileC), NIL)); 204 END; 205 END; 206 207 IF installObjects THEN 208 RETURN TRUE; 209 ELSIF InstallDirectory("", CCompiler.libdir.value(CfgData.StringVar).string) THEN 210 uri := module.GetURI(Rep.modLibrary, TRUE); 211 cmd := CCompiler.InstallProgramCmd(uri, TRUE); 212 Logger.ShellCommand(cmd); 213 RETURN (ProcessManagement.system(cmd) = 0); 214 ELSE 215 RETURN FALSE; 216 END; 217 END InstallLibrary; 218 219 PROCEDURE InstallExecutable(module: Rep.Module): BOOLEAN; 220 (* pre: Full update has been done for the program's main module. *) 221 VAR 222 uri: URI.URI; 223 cmd: STRING; 224 BEGIN 225 IF InstallDirectory("", CCompiler.bindir.value(CfgData.StringVar).string) THEN 226 uri := module.GetURI(Rep.modExecutable, TRUE); 227 cmd := CCompiler.InstallProgramCmd(uri, FALSE); 228 Logger.ShellCommand(cmd); 229 RETURN (ProcessManagement.system(cmd) = 0); 230 ELSE 231 RETURN FALSE; 232 END; 233 END InstallExecutable; 234 235 PROCEDURE InstallFiles(list: Package.FileData): BOOLEAN; 236 VAR 237 end: Package.FileData; 238 dir, str, sourcePrefix: STRING; 239 cmd: StringBuffer.StringBuffer; 240 baseURI: URI.URI; 241 chars: Object.CharsLatin1; 242 243 (*PROCEDURE SameDirectory(a, b: Package.File): BOOLEAN; 244 VAR 245 sa, sb: STRING; 246 i, j: LONGINT; 247 BEGIN 248 sa := a.destName; sb := b.destName; 249 i := 0; 250 WHILE (i # sa.length) & (i # sb.length) & 251 (sa.CharAt(i) = sb.CharAt(i)) DO 252 INC(i); 253 END; 254 WHILE (i # 0) & (sa.CharAt(i-1) # "/") DO 255 DEC(i); 256 END; 257 258 IF (i = 0) OR 259 ((sa.CharAt(i-1) = "/") & 260 (sb.CharAt(i-1) = "/")) THEN 261 (* sa and sb have the same prefix ending with a "/"; check that both 262 have no "/" in the rest of their path *) 263 j := i; 264 WHILE (j # sa.length) & (sa.CharAt(j) # "/") DO 265 INC (j); 266 END; 267 IF (j = sa.length) THEN 268 j := i; 269 WHILE (j # sb.length) & (sb.CharAt(j) # "/") DO 270 INC (j); 271 END; 272 RETURN (j = sb.length) 273 END; 274 END; 275 RETURN FALSE; 276 END SameDirectory;*) 277 278 BEGIN 279 baseURI := rep(FileSystem.Repository).relativeBaseURI; 280 sourcePrefix := baseURI(File.URI).GetPath(); 281 282 WHILE (list # NIL) DO 283 end := list.nextFileData; 284 (* don't call install with multiple input files: the fallback script 285 install-sh does not support this 286 287 WHILE (end # NIL) & 288 SameDirectory(list(Package.File), end(Package.File)) DO 289 end := end.nextFileData; 290 END;*) 291 292 dir := Path.DirName(list(Package.File).destName); 293 294 chars := dir(Object.String8).CharsLatin1(); 295 IF InstallDirectory(CCompiler.oocdir.value(CfgData.StringVar).string, 296 dir(Object.String8)) THEN 297 cmd := StringBuffer.New(CCompiler.installData.value(CfgData.StringVar).string); 298 WHILE (list # end) DO 299 cmd.Append(" "); 300 cmd.Append(Path.QuoteForShell(sourcePrefix+list(Package.File).name)); 301 list := list.nextFileData; 302 END; 303 304 cmd.Append(" "); 305 IF (CCompiler.oocdir.value(CfgData.StringVar).string.length # 0) THEN 306 cmd.Append(Path.QuoteForShell(CCompiler.oocdir.value(CfgData.StringVar).string)); 307 IF (dir.length # 0) THEN 308 cmd.Append("/"); 309 END; 310 END; 311 cmd.Append(Path.QuoteForShell(dir)); 312 313 str := cmd.ToString(); 314 Logger.ShellCommand(str); 315 IF (ProcessManagement.system(str) # 0) THEN 316 RETURN FALSE; 317 END; 318 ELSE 319 RETURN FALSE; 320 END; 321 END; 322 RETURN TRUE; 323 END InstallFiles; 324 325 PROCEDURE BuildDocs(module: Rep.Module; makeRules: Make.Rules; 326 install: BOOLEAN): BOOLEAN 327 RAISES IO.Error; 328 VAR 329 m: Rep.Module; 330 ok: BOOLEAN; 331 i: LONGINT; 332 BEGIN 333 ok := TRUE; 334 IF Config.HaveXsltProc() THEN 335 i := 0; 336 WHILE ok & (i # LEN(makeRules.imports^)) DO 337 m := makeRules.imports[i]; 338 IF (m.origin = module.origin) THEN 339 IF install THEN 340 pkg.fileSet.Append(Package.NewFile(m.origin.GetLocalPath(m, Rep.modInterfaceDescr), NIL)); 341 pkg.fileSet.Append(Package.NewFile(m.origin.GetLocalPath(m, Rep.modInterfaceHTML), NIL)); 342 ELSE 343 ok := makeRules.Update(m, Rep.modInterfaceHTML); 344 END; 345 END; 346 INC(i); 347 END; 348 END; 349 RETURN ok; 350 END BuildDocs; 351 352 BEGIN 353 Rep.readDocStrings := TRUE; 354 installObjects := ~CCompiler.HaveLibtool(); 355 ok := TRUE; 356 357 i := 0; 358 WHILE ok & (i # pkg.library.size) DO 359 lib := pkg.library.array[i]; 360 361 module := GetModule(lib.mainModule); 362 IF installObjects THEN 363 ok := makeRules.Update(module, Rep.modExecutable) 364 & (~install OR InstallLibrary(module, makeRules)); 365 ELSE 366 makeRules.SetLibrary(lib); 367 ok := makeRules.Update(module, Rep.modLibrary) 368 & (~install OR InstallLibrary(module, makeRules)); 369 END; 370 371 IF ok THEN 372 (* build HTML documentation for modules in library *) 373 ok := BuildDocs(module, makeRules, install); 374 END; 375 376 makeRules.SetLibrary(NIL); 377 INC(i); 378 END; 379 380 i := 0; 381 WHILE ok & (i # pkg.executable.size) DO 382 exec := pkg.executable.array[i]; 383 module := GetModule(exec.mainModule); 384 ok := makeRules.Update(module, Rep.modExecutable) 385 & (~install OR InstallExecutable(module)); 386 INC(i); 387 END; 388 389 IF ok & install THEN 390 normSet := Package.Normalize(pkg.fileSet); 391 ok := InstallFiles(normSet.head); 392 END; 393 394 IF ok & install THEN 395 Package.WritePackage(pkg, 396 CCompiler.oocdir.value(CfgData.StringVar).string); 397 END; 398 399 RETURN ok; 400 END BuildPackage; 401 402PROCEDURE UninstallPackage(pkg: Package.Package); 403 VAR 404 i: LONGINT; 405 normSet: Package.FileSet; 406 407 PROCEDURE UninstallLibrary(library: Package.Library); 408 VAR 409 cmd: STRING; 410 ok: BOOLEAN; 411 b: StringBuffer.StringBuffer; 412 BEGIN 413 b := StringBuffer.NewLatin1(""); 414 b.Append(CCompiler.libdir.value(CfgData.StringVar).string); 415 b.Append("/lib"); 416 b.Append(library.name); 417 b.Append(".la"); 418 cmd := CCompiler.UninstallProgramCmd(b.ToString(), TRUE); 419 Logger.ShellCommand(cmd); 420 ok := (ProcessManagement.system(cmd) = 0); 421 END UninstallLibrary; 422 423 PROCEDURE UninstallExecutable(executable: Package.Executable); 424 VAR 425 cmd: STRING; 426 ok: BOOLEAN; 427 b: StringBuffer.StringBuffer; 428 BEGIN 429 b := StringBuffer.NewLatin1(""); 430 b.Append(CCompiler.bindir.value(CfgData.StringVar).string); 431 b.Append("/"); 432 b.Append(executable.mainModule); 433 cmd := CCompiler.UninstallProgramCmd(b.ToString(), FALSE); 434 Logger.ShellCommand(cmd); 435 ok := (ProcessManagement.system(cmd) = 0); 436 END UninstallExecutable; 437 438 PROCEDURE UninstallFiles(list: Package.FileData); 439 VAR 440 str: STRING; 441 ok: BOOLEAN; 442 b: StringBuffer.StringBuffer; 443 BEGIN 444 WHILE (list # NIL) DO 445 b := StringBuffer.New(CCompiler.uninstall.value(CfgData.StringVar).string); 446 b.Append(" "); 447 b.Append(Path.QuoteForShell(CCompiler.oocdir.value(CfgData.StringVar).string)); 448 b.Append("/"); 449 b.Append(list(Package.File).destName); 450 451 str := b.ToString(); 452 Logger.ShellCommand(str); 453 ok := (ProcessManagement.system(str) = 0); 454 list := list.nextFileData; 455 END; 456 END UninstallFiles; 457 458 PROCEDURE UninstallPkgInfo(pkg: Package.Package); 459 VAR 460 ok: BOOLEAN; 461 cmd: STRING; 462 BEGIN 463 cmd := Package.RemovePkgInfoCmd 464 (pkg, 465 CCompiler.oocdir.value(CfgData.StringVar).string, 466 CCompiler.uninstall.value(CfgData.StringVar).string); 467 Logger.ShellCommand(cmd); 468 ok := (ProcessManagement.system(cmd) = 0); 469 END UninstallPkgInfo; 470 471 BEGIN 472 i := 0; 473 WHILE (i # pkg.library.size) DO 474 UninstallLibrary(pkg.library.array[i]); 475 INC(i); 476 END; 477 478 i := 0; 479 WHILE (i # pkg.executable.size) DO 480 UninstallExecutable(pkg.executable.array[i]); 481 INC(i); 482 END; 483 484 normSet := Package.Normalize(pkg.fileSet); 485 UninstallFiles(normSet.head); 486 487 UninstallPkgInfo(pkg); 488 END UninstallPackage; 489 490PROCEDURE BuildPackageDoc(pkg: Package.Package): BOOLEAN 491RAISES IO.Error; 492 VAR 493 ok: BOOLEAN; 494 i: LONGINT; 495 lib: Package.Library; 496 exec: Package.Executable; 497 498 PROCEDURE BuildDocs(module: Rep.Module): BOOLEAN 499 RAISES IO.Error; 500 VAR 501 ok: BOOLEAN; 502 i: LONGINT; 503 list: Make.ModuleList; 504 BEGIN 505 ok := makeRules.Update(module, Rep.modSymbolFile); 506 507 list := Make.ModuleClosure(module); 508 i := 0; 509 WHILE ok & (i # LEN(list^)) DO 510 IF (list[i].origin = module.origin) THEN 511 ok := makeRules.Update(list[i], Rep.modInterfaceHTML); 512 END; 513 INC(i); 514 END; 515 RETURN ok; 516 END BuildDocs; 517 518 BEGIN 519 Rep.readDocStrings := TRUE; 520 ok := TRUE; 521 522 i := 0; 523 WHILE ok & (i # pkg.library.size) DO 524 lib := pkg.library.array[i]; 525 ok := BuildDocs(GetModule(lib.mainModule)); 526 INC(i); 527 END; 528 529 i := 0; 530 WHILE ok & (i # pkg.executable.size) DO 531 exec := pkg.executable.array[i]; 532 ok := BuildDocs(GetModule(exec.mainModule)); 533 INC(i); 534 END; 535 536 RETURN ok; 537 END BuildPackageDoc; 538 539PROCEDURE WriteHelp(); 540 BEGIN 541 Out.String("Usage:"); Out.Ln; 542 Out.String(" oo2c [options] <module>..."); Out.Ln; 543 Out.String(" oo2c (--make|-M) [options] <module>"); Out.Ln; 544 Out.String(" oo2c --uses <ext-ident> [options] <module> ..."); Out.Ln; 545 Out.String(" oo2c --build-package [options] <package>"); Out.Ln; 546 Out.String(" oo2c --install-package [options] <package>"); Out.Ln; 547 Out.String(" oo2c --uninstall-package [options] <package>"); Out.Ln; 548 Out.String(" oo2c --build-pkg-doc [options] <package>"); Out.Ln; 549 Out.String(" oo2c --package-installed [options] <package>"); Out.Ln; 550 Out.String(" oo2c --list-packages [options]"); Out.Ln; 551 Out.String("Options:"); Out.Ln; 552 Out.String(" --config <file>"); Out.Ln; 553 Out.String(" --repository <directory>, -r <directory>"); Out.Ln; 554 Out.String(" --no-rtc"); Out.Ln; 555 Out.String(" (--all|-A)"); Out.Ln; 556 Out.String(" --error-style (file:line:column|char-pos|attributes)"); 557 Out.Ln; 558 END WriteHelp; 559 560BEGIN <*Warnings:=FALSE*> 561 Error.minErrorDistance := 16; 562 Builder.doAutoImport := Builder.fullAutoImport; 563 cfgErrList := Error.NewList (""); 564 NewConfig; 565 Config.Read (cfgErrList); 566 567 makeRules := Make.NewRules(); 568 IF useStderr.value(CfgData.BooleanVar).boolean THEN 569 makeRules.SetErrOut(StdChannels.stderr); 570 END; 571 makeRules.SetForceUpdate(forceUpdate.value(CfgData.BooleanVar).boolean); 572 ok := makeRules.UsageTracking(listUses.value(CfgData.StringVar).string); 573 IF ~ok THEN 574 Err.String ("Error: Invalid selector string for `--uses'"); 575 Err.Ln; 576 HALT (1) 577 END; 578 Make.writeStats := writeStats.value(CfgData.BooleanVar).boolean; 579 Logger.silence := ~verbose.value(CfgData.BooleanVar).boolean; 580 581 CASE command.value(CfgData.IntegerVar).integer OF 582 | 0: 583 mode := Rep.modCodeFileC; 584 | 1: 585 mode := Rep.modExecutable; 586 | 2: 587 mode := buildPackage; 588 | 3: 589 mode := installPackage; 590 | 4: 591 mode := uninstallPackage; 592 | 5: 593 mode := updateRepository; 594 | 6: 595 mode := getOption; Logger.silence := TRUE; 596 | 7: 597 mode := buildPackageDoc; 598 | 8: 599 mode := packageInstalled; Logger.silence := TRUE; 600 | 9: 601 mode := listPackages; Logger.silence := TRUE; 602 END; 603 IF errorStyle.value(CfgData.StringVar).string.Equals("file:line:column") THEN 604 Error.style := Error.styleFileLineColumn; 605 ELSIF errorStyle.value(CfgData.StringVar).string.Equals("char-pos") THEN 606 Error.style := Error.styleCharPos; 607 END; 608 609 IF (cfgErrList. msgCount # 0) THEN 610 cfgErrList. Write (StdChannels.stderr); 611 HALT(1); 612 ELSIF showVersion.value(CfgData.BooleanVar).boolean THEN 613 Out.String("oo2c/"); 614 Out.String(StdPragmas.defaultTargetArch); 615 Out.String(" "); 616 Out.String(StdPragmas.defaultCompilerVersion); 617 Out.Ln; 618 HALT(0); 619 ELSIF showHelp.value(CfgData.BooleanVar).boolean THEN 620 WriteHelp; 621 ELSIF ((mode = updateRepository) OR (mode = listPackages)) 622 # (Config.arguments. ArgNumber() = 0) THEN 623 WriteHelp; 624 HALT (1) 625 ELSE 626 ok := TRUE; 627 628 IF (mode = updateRepository) THEN 629 ok := Package.UpdateRepository(CCompiler.oocdir.value(CfgData.StringVar).string); 630 631 ELSIF (mode = listPackages) THEN 632 r := Package.GetRepository(CCompiler.oocdir.value(CfgData.StringVar).string, errList); 633 errList.Write(StdChannels.stderr); 634 FOR i := 0 TO r.installedPkgs.size-1 DO 635 Out.Object(r.installedPkgs.array[i]); Out.Ln; 636 END; 637 638 ELSE 639 IF ~Package.ParseMetaData(Config.options, Config.pragmas) THEN 640 HALT(1); 641 END; 642 643 forceUpdateRepository := FALSE; 644 i := 0; 645 WHILE ok & (i # Config.arguments. ArgNumber()) DO 646 arg := Config.arguments. Get (i); 647 CASE mode OF 648 | buildPackage, installPackage: 649 doInstall := (mode = installPackage); 650 pkg := Package.GetPackage(arg, rep); 651 IF (pkg = NIL) THEN 652 Err.String ("Error: Cannot locate package "); 653 Err.Object (arg); 654 Err.Ln; 655 HALT (1) 656 ELSE 657 IF doInstall THEN 658 pkgInfo := Package.GetPkgInfo(CCompiler.oocdir.value(CfgData.StringVar).string, arg, errList); 659 IF (pkgInfo # NIL) & (errList.msgCount = 0) THEN 660 UninstallPackage(pkgInfo); 661 END; 662 END; 663 ok := BuildPackage(pkg, rep, doInstall); 664 forceUpdateRepository := doInstall; 665 END; 666 667 | uninstallPackage: 668 pkg := Package.GetPkgInfo(CCompiler.oocdir.value(CfgData.StringVar).string, arg, errList); 669 IF (errList.msgCount # 0) THEN 670 errList.Write(StdChannels.stdout); 671 END; 672 IF (pkg = NIL) THEN 673 Err.String ("Error: Cannot locate package "); 674 Err.Object (arg); 675 Err.Ln; 676 HALT (1) 677 ELSE 678 UninstallPackage(pkg); 679 forceUpdateRepository := TRUE; 680 END; 681 682 683 | getOption: 684 option := Config.options.Get(arg); 685 IF (option = NIL) THEN 686 Out.String("(none)"); 687 ELSE 688 Out.Object(option.value(CfgData.StringVar).string); 689 END; 690 Out.Ln; 691 692 | buildPackageDoc: 693 pkg := Package.GetPackage(arg, rep); 694 IF (pkg = NIL) THEN 695 Err.String ("Error: Cannot locate package "); 696 Err.Object (arg); 697 Err.Ln; 698 HALT (1) 699 ELSE 700 ok := BuildPackageDoc(pkg); 701 END; 702 703 | packageInstalled: 704 r := Package.GetRepository(CCompiler.oocdir.value(CfgData.StringVar).string, errList); 705 errList.Write(StdChannels.stderr); 706 IF r.PackageInstalled(arg) THEN 707 HALT(0); 708 ELSE 709 HALT(1); 710 END; 711 712 ELSE 713 module := GetModule(arg); 714 IF (mode = Rep.modCodeFileC) THEN 715 makeRules.SetAllImportsModule(module); 716 END; 717 ok := makeRules.Update(module, mode); 718 makeRules.SetAllImportsModule(NIL); 719 END; 720 INC(i); 721 END; 722 723 IF ok & forceUpdateRepository THEN 724 ok := Package.UpdateRepository(CCompiler.oocdir.value(CfgData.StringVar).string); 725 END; 726 END; 727 728 IF ok THEN 729 IF Make.writeStats THEN 730 Stats.Write(); 731 END; 732 ELSE 733 HALT (1) 734 END 735 END 736END oo2c. 737