llvm.org GIT mirror llvm / 975bc07
Adjust llvm-ar and llvm-ranlib to not depend on exception handling. Always use an exit code of 1, but print the help message if useful. Remove the exception handling tag in llvm-as, llvm-dis and llvm-bcanalyzer, where it isn't used. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@166767 91177308-0d34-0410-b5e6-96231b3b80d8 Joerg Sonnenberger 6 years ago
9 changed file(s) with 134 addition(s) and 139 deletion(s). Raw diff Collapse all Expand all
0 set(LLVM_LINK_COMPONENTS archive)
1 set(LLVM_REQUIRES_EH 1)
21
32 add_llvm_tool(llvm-ar
43 llvm-ar.cpp
99 LEVEL := ../..
1010 TOOLNAME := llvm-ar
1111 LINK_COMPONENTS := archive
12 REQUIRES_EH := 1
1312
1413 # This tool has no plugins, optimize startup time.
1514 TOOL_NO_EXPORTS := 1
2222 #include "llvm/Support/raw_ostream.h"
2323 #include "llvm/Support/Signals.h"
2424 #include
25 #include
2526 #include
2627 #include
2728 using namespace llvm;
125126 // The Archive object to which all the editing operations will be sent.
126127 Archive* TheArchive = 0;
127128
129 // The name this program was invoked as.
130 static const char *program_name;
131
132 // show_help - Show the error message, the help message and exit.
133 LLVM_ATTRIBUTE_NORETURN static void
134 show_help(const std::string &msg) {
135 errs() << program_name << ": " << msg << "\n\n";
136 cl::PrintHelpMessage();
137 if (TheArchive)
138 delete TheArchive;
139 std::exit(1);
140 }
141
142 // fail - Show the error message and exit.
143 LLVM_ATTRIBUTE_NORETURN static void
144 fail(const std::string &msg) {
145 errs() << program_name << ": " << msg << "\n\n";
146 if (TheArchive)
147 delete TheArchive;
148 std::exit(1);
149 }
150
128151 // getRelPos - Extract the member filename from the command line for
129152 // the [relpos] argument associated with a, b, and i modifiers
130153 void getRelPos() {
131 if(RestOfArgs.size() > 0) {
132 RelPos = RestOfArgs[0];
133 RestOfArgs.erase(RestOfArgs.begin());
134 }
135 else
136 throw "Expected [relpos] for a, b, or i modifier";
154 if(RestOfArgs.size() == 0)
155 show_help("Expected [relpos] for a, b, or i modifier");
156 RelPos = RestOfArgs[0];
157 RestOfArgs.erase(RestOfArgs.begin());
137158 }
138159
139160 // getCount - Extract the [count] argument associated with the N modifier
140161 // from the command line and check its value.
141162 void getCount() {
142 if(RestOfArgs.size() > 0) {
143 Count = atoi(RestOfArgs[0].c_str());
144 RestOfArgs.erase(RestOfArgs.begin());
145 }
146 else
147 throw "Expected [count] value with N modifier";
163 if(RestOfArgs.size() == 0)
164 show_help("Expected [count] value with N modifier");
165
166 Count = atoi(RestOfArgs[0].c_str());
167 RestOfArgs.erase(RestOfArgs.begin());
148168
149169 // Non-positive counts are not allowed
150170 if (Count < 1)
151 throw "Invalid [count] value (not a positive integer)";
171 show_help("Invalid [count] value (not a positive integer)");
152172 }
153173
154174 // getArchive - Get the archive file name from the command line
155175 void getArchive() {
156 if(RestOfArgs.size() > 0) {
157 ArchiveName = RestOfArgs[0];
158 RestOfArgs.erase(RestOfArgs.begin());
159 }
160 else
161 throw "An archive name must be specified.";
176 if(RestOfArgs.size() == 0)
177 show_help("An archive name must be specified");
178 ArchiveName = RestOfArgs[0];
179 RestOfArgs.erase(RestOfArgs.begin());
162180 }
163181
164182 // getMembers - Copy over remaining items in RestOfArgs to our Members vector
239257 // Perform various checks on the operation/modifier specification
240258 // to make sure we are dealing with a legal request.
241259 if (NumOperations == 0)
242 throw "You must specify at least one of the operations";
260 show_help("You must specify at least one of the operations");
243261 if (NumOperations > 1)
244 throw "Only one operation may be specified";
262 show_help("Only one operation may be specified");
245263 if (NumPositional > 1)
246 throw "You may only specify one of a, b, and i modifiers";
247 if (AddAfter || AddBefore || InsertBefore)
264 show_help("You may only specify one of a, b, and i modifiers");
265 if (AddAfter || AddBefore || InsertBefore) {
248266 if (Operation != Move && Operation != ReplaceOrInsert)
249 throw "The 'a', 'b' and 'i' modifiers can only be specified with "
250 "the 'm' or 'r' operations";
267 show_help("The 'a', 'b' and 'i' modifiers can only be specified with "
268 "the 'm' or 'r' operations");
269 }
251270 if (RecurseDirectories && Operation != ReplaceOrInsert)
252 throw "The 'R' modifiers is only applicabe to the 'r' operation";
271 show_help("The 'R' modifiers is only applicabe to the 'r' operation");
253272 if (OriginalDates && Operation != Extract)
254 throw "The 'o' modifier is only applicable to the 'x' operation";
273 show_help("The 'o' modifier is only applicable to the 'x' operation");
255274 if (TruncateNames && Operation!=QuickAppend && Operation!=ReplaceOrInsert)
256 throw "The 'f' modifier is only applicable to the 'q' and 'r' operations";
275 show_help("The 'f' modifier is only applicable to the 'q' and 'r' "
276 "operations");
257277 if (OnlyUpdate && Operation != ReplaceOrInsert)
258 throw "The 'u' modifier is only applicable to the 'r' operation";
278 show_help("The 'u' modifier is only applicable to the 'r' operation");
259279 if (Count > 1 && Members.size() > 1)
260 throw "Only one member name may be specified with the 'N' modifier";
280 show_help("Only one member name may be specified with the 'N' modifier");
261281
262282 // Return the parsed operation to the caller
263283 return Operation;
303323 for (unsigned i = 0; i < Members.size(); i++) {
304324 sys::Path aPath;
305325 if (!aPath.set(Members[i]))
306 throw std::string("File member name invalid: ") + Members[i];
326 fail(std::string("File member name invalid: ") + Members[i]);
307327 if (checkExistence) {
308328 bool Exists;
309329 if (sys::fs::exists(aPath.str(), Exists) || !Exists)
310 throw std::string("File does not exist: ") + Members[i];
330 fail(std::string("File does not exist: ") + Members[i]);
311331 std::string Err;
312332 sys::PathWithStatus PwS(aPath);
313333 const sys::FileStatus *si = PwS.getFileStatus(false, &Err);
314334 if (!si)
315 throw Err;
335 fail(Err);
316336 if (si->isDir) {
317337 std::set dirpaths;
318338 if (recurseDirectories(aPath, dirpaths, ErrMsg))
682702
683703 // main - main program for llvm-ar .. see comments in the code
684704 int main(int argc, char **argv) {
705 program_name = argv[0];
685706 // Print a stack trace if we signal out.
686707 sys::PrintStackTraceOnErrorSignal();
687708 PrettyStackTraceProgram X(argc, argv);
697718
698719 int exitCode = 0;
699720
700 // Make sure we don't exit with "unhandled exception".
701 try {
702 // Do our own parsing of the command line because the CommandLine utility
703 // can't handle the grouped positional parameters without a dash.
704 ArchiveOperation Operation = parseCommandLine();
705
706 // Check the path name of the archive
707 sys::Path ArchivePath;
708 if (!ArchivePath.set(ArchiveName))
709 throw std::string("Archive name invalid: ") + ArchiveName;
710
711 // Create or open the archive object.
712 bool Exists;
713 if (llvm::sys::fs::exists(ArchivePath.str(), Exists) || !Exists) {
714 // Produce a warning if we should and we're creating the archive
715 if (!Create)
716 errs() << argv[0] << ": creating " << ArchivePath.str() << "\n";
717 TheArchive = Archive::CreateEmpty(ArchivePath, Context);
718 TheArchive->writeToDisk();
719 } else {
720 std::string Error;
721 TheArchive = Archive::OpenAndLoad(ArchivePath, Context, &Error);
722 if (TheArchive == 0) {
723 errs() << argv[0] << ": error loading '" << ArchivePath.str() << "': "
724 << Error << "!\n";
725 return 1;
726 }
727 }
728
729 // Make sure we're not fooling ourselves.
730 assert(TheArchive && "Unable to instantiate the archive");
731
732 // Make sure we clean up the archive even on failure.
733 std::auto_ptr AutoArchive(TheArchive);
734
735 // Perform the operation
736 std::string ErrMsg;
737 bool haveError = false;
738 switch (Operation) {
739 case Print: haveError = doPrint(&ErrMsg); break;
740 case Delete: haveError = doDelete(&ErrMsg); break;
741 case Move: haveError = doMove(&ErrMsg); break;
742 case QuickAppend: haveError = doQuickAppend(&ErrMsg); break;
743 case ReplaceOrInsert: haveError = doReplaceOrInsert(&ErrMsg); break;
744 case DisplayTable: haveError = doDisplayTable(&ErrMsg); break;
745 case Extract: haveError = doExtract(&ErrMsg); break;
746 case NoOperation:
747 errs() << argv[0] << ": No operation was selected.\n";
748 break;
749 }
750 if (haveError) {
751 errs() << argv[0] << ": " << ErrMsg << "\n";
721 // Do our own parsing of the command line because the CommandLine utility
722 // can't handle the grouped positional parameters without a dash.
723 ArchiveOperation Operation = parseCommandLine();
724
725 // Check the path name of the archive
726 sys::Path ArchivePath;
727 if (!ArchivePath.set(ArchiveName)) {
728 errs() << argv[0] << ": Archive name invalid: " << ArchiveName << "\n";
729 return 1;
730 }
731
732 // Create or open the archive object.
733 bool Exists;
734 if (llvm::sys::fs::exists(ArchivePath.str(), Exists) || !Exists) {
735 // Produce a warning if we should and we're creating the archive
736 if (!Create)
737 errs() << argv[0] << ": creating " << ArchivePath.str() << "\n";
738 TheArchive = Archive::CreateEmpty(ArchivePath, Context);
739 TheArchive->writeToDisk();
740 } else {
741 std::string Error;
742 TheArchive = Archive::OpenAndLoad(ArchivePath, Context, &Error);
743 if (TheArchive == 0) {
744 errs() << argv[0] << ": error loading '" << ArchivePath.str() << "': "
745 << Error << "!\n";
752746 return 1;
753747 }
754 } catch (const char*msg) {
755 // These errors are usage errors, thrown only by the various checks in the
756 // code above.
757 errs() << argv[0] << ": " << msg << "\n\n";
758 cl::PrintHelpMessage();
759 exitCode = 1;
760 } catch (const std::string& msg) {
761 // These errors are thrown by LLVM libraries (e.g. lib System) and represent
762 // a more serious error so we bump the exitCode and don't print the usage.
763 errs() << argv[0] << ": " << msg << "\n";
764 exitCode = 2;
765 } catch (...) {
766 // This really shouldn't happen, but just in case ....
767 errs() << argv[0] << ": An unexpected unknown exception occurred.\n";
768 exitCode = 3;
769 }
748 }
749
750 // Make sure we're not fooling ourselves.
751 assert(TheArchive && "Unable to instantiate the archive");
752
753 // Perform the operation
754 std::string ErrMsg;
755 bool haveError = false;
756 switch (Operation) {
757 case Print: haveError = doPrint(&ErrMsg); break;
758 case Delete: haveError = doDelete(&ErrMsg); break;
759 case Move: haveError = doMove(&ErrMsg); break;
760 case QuickAppend: haveError = doQuickAppend(&ErrMsg); break;
761 case ReplaceOrInsert: haveError = doReplaceOrInsert(&ErrMsg); break;
762 case DisplayTable: haveError = doDisplayTable(&ErrMsg); break;
763 case Extract: haveError = doExtract(&ErrMsg); break;
764 case NoOperation:
765 errs() << argv[0] << ": No operation was selected.\n";
766 break;
767 }
768 if (haveError) {
769 errs() << argv[0] << ": " << ErrMsg << "\n";
770 return 1;
771 }
772
773 delete TheArchive;
774 TheArchive = 0;
770775
771776 // Return result code back to operating system.
772777 return exitCode;
0 set(LLVM_LINK_COMPONENTS asmparser bitwriter)
1 set(LLVM_REQUIRES_EH 1)
21
32 add_llvm_tool(llvm-as
43 llvm-as.cpp
0 set(LLVM_LINK_COMPONENTS bitreader)
1 set(LLVM_REQUIRES_EH 1)
21
32 add_llvm_tool(llvm-bcanalyzer
43 llvm-bcanalyzer.cpp
0 set(LLVM_LINK_COMPONENTS bitreader analysis)
1 set(LLVM_REQUIRES_EH 1)
21
32 add_llvm_tool(llvm-dis
43 llvm-dis.cpp
0 set(LLVM_LINK_COMPONENTS archive)
1 set(LLVM_REQUIRES_EH 1)
21
32 add_llvm_tool(llvm-ranlib
43 llvm-ranlib.cpp
99 LEVEL := ../..
1010 TOOLNAME := llvm-ranlib
1111 LINK_COMPONENTS := archive
12 REQUIRES_EH := 1
1312
1413 # This tool has no plugins, optimize startup time.
1514 TOOL_NO_EXPORTS := 1
6060
6161 int exitCode = 0;
6262
63 // Make sure we don't exit with "unhandled exception".
64 try {
63 // Check the path name of the archive
64 sys::Path ArchivePath;
65 if (!ArchivePath.set(ArchiveName)) {
66 errs() << argv[0] << ": " << "Archive name invalid: " << ArchiveName <<
67 "\n";
68 return 1;
69 }
6570
66 // Check the path name of the archive
67 sys::Path ArchivePath;
68 if (!ArchivePath.set(ArchiveName))
69 throw std::string("Archive name invalid: ") + ArchiveName;
71 // Make sure it exists, we don't create empty archives
72 bool Exists;
73 if (llvm::sys::fs::exists(ArchivePath.str(), Exists) || !Exists) {
74 errs() << argv[0] << ": " << "Archive file does not exist" <<
75 ArchivePath.str() << "\n";
76 return 1;
77 }
7078
71 // Make sure it exists, we don't create empty archives
72 bool Exists;
73 if (llvm::sys::fs::exists(ArchivePath.str(), Exists) || !Exists)
74 throw std::string("Archive file does not exist");
79 std::string err_msg;
80 std::auto_ptr
81 AutoArchive(Archive::OpenAndLoad(ArchivePath, Context, &err_msg));
82 Archive* TheArchive = AutoArchive.get();
83 if (!TheArchive) {
84 errs() << argv[0] << ": " << err_msg << "\n";
85 return 1;
86 }
7587
76 std::string err_msg;
77 std::auto_ptr
78 AutoArchive(Archive::OpenAndLoad(ArchivePath, Context, &err_msg));
79 Archive* TheArchive = AutoArchive.get();
80 if (!TheArchive)
81 throw err_msg;
88 if (TheArchive->writeToDisk(true, false, &err_msg )) {
89 errs() << argv[0] << ": " << err_msg << "\n";
90 return 1;
91 }
8292
83 if (TheArchive->writeToDisk(true, false, &err_msg ))
84 throw err_msg;
93 if (Verbose)
94 printSymbolTable(TheArchive);
8595
86 if (Verbose)
87 printSymbolTable(TheArchive);
88
89 } catch (const char* msg) {
90 errs() << argv[0] << ": " << msg << "\n\n";
91 exitCode = 1;
92 } catch (const std::string& msg) {
93 errs() << argv[0] << ": " << msg << "\n";
94 exitCode = 2;
95 } catch (...) {
96 errs() << argv[0] << ": An unexpected unknown exception occurred.\n";
97 exitCode = 3;
98 }
9996 return exitCode;
10097 }