1 using System;
  2 using System.IO;
  3 using System.Collections;
  4 using cmsx.object;
  5 
  6 public nothrow const char* Version()
  7 {
  8     return "4.0.0";
  9 }
 10 
 11 void PrintHelp()
 12 {
 13     Console.Out() << "Cmajor System X Archiver version " << Version() << endl();
 14     Console.Out() << "Usage: cmsxar [options] { file.o }" << endl();
 15     Console.Out() << "Options:" << endl();
 16     Console.Out() << "--verbose (-v)" << endl();
 17     Console.Out() << "  be verbose" << endl();
 18     Console.Out() << "--help (-h)" << endl();
 19     Console.Out() << "  print help" << endl();
 20     Console.Out() << "--out=FILE.a (-o=FILE.a)" << endl();
 21     Console.Out() << "  set output file name to 'FILE.a'." << endl();
 22 }
 23 
 24 int main(int argcconst char** argv)
 25 {
 26     try
 27     {
 28         bool verbose = false;
 29         string libraryFileName;
 30         List<string> objectFileNames;
 31         for (int i = 1; i < argc; ++i;)
 32         {
 33             string arg = argv[i];
 34             if (arg.StartsWith("--"))
 35             {
 36                 if (arg == "--help")
 37                 {
 38                     PrintHelp();
 39                     return 1;
 40                 }
 41                 else if (arg == "--verbose")
 42                 {
 43                     verbose = true;
 44                 }
 45                 else if (arg.StartsWith("--out="))
 46                 {
 47                     libraryFileName = GetFullPath(arg.Substring(6));
 48                 }
 49                 else
 50                 {
 51                     throw Exception("unknown option '" + arg + "'");
 52                 }
 53             }
 54             else if (arg.StartsWith("-"))
 55             {
 56                 if (arg.StartsWith("-o="))
 57                 {
 58                     libraryFileName = GetFullPath(arg.Substring(3));
 59                 }
 60                 else
 61                 {
 62                     string options = arg.Substring(1);
 63                     if (options.IsEmpty())
 64                     {
 65                         throw Exception("unknown option '" + arg + "'");
 66                     }
 67                     else
 68                     {
 69                         for (char o : options)
 70                         {
 71                             if (o == 'h')
 72                             {
 73                                 PrintHelp();
 74                                 return 1;
 75                             }
 76                             else if (o == 'v')
 77                             {
 78                                 verbose = true;
 79                             }
 80                             else
 81                             {
 82                                 throw Exception("unknown option '-" + string(o) + "'");
 83                             }
 84                         }
 85                     }
 86                 }
 87             }
 88             else
 89             {
 90                 objectFileNames.Add(GetFullPath(arg));
 91             }
 92         }
 93         if (verbose)
 94         {
 95             Console.Out() << "Cmajor System X Archiver version " << Version() << endl();
 96         }
 97         if (objectFileNames.IsEmpty())
 98         {
 99             PrintHelp();
100             throw Exception("no object files given");
101         }
102         if (libraryFileName.IsEmpty())
103         {
104             PrintHelp();
105             throw Exception("no library file name given");
106         }
107         List<UniquePtr<BinaryFile>> binaryFiles;
108         for (const string& objectFileName : objectFileNames)
109         {
110             if (verbose)
111             {
112                 Console.Out() << "> " << objectFileName << endl();
113             }
114             UniquePtr<BinaryFile> binaryFile = ReadBinaryFile(objectFileName);
115             binaryFile->AddSymbolsToAddressMap();
116             binaryFiles.Add(Rvalue(binaryFile));
117         }
118         LibraryFile libraryFile(libraryFileNametrue);
119         for (UniquePtr<BinaryFile>& binaryFile : binaryFiles)
120         {
121             if (binaryFile.Get() is ObjectFile*)
122             {
123                 libraryFile.objectFiles.Add(UniquePtr<ObjectFile>(cast<ObjectFile*>(binaryFile.Release())));
124             }
125             else
126             {
127                 throw Exception("file '" + binaryFile->FileName() + "' is not a CMSX object file");
128             }
129         }
130         libraryFile.Write();
131         if (verbose)
132         {
133             Console.Out() << "==> " << libraryFileName << endl();
134         }
135     }
136     catch (const Exception& ex)
137     {
138         Console.Error() << ex.Message() << endl();
139         return 1;
140     }
141     return 0;
142 }