main.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. /* main.c: Main entry point for ar-tigcc, handling the command line input
  2. Copyright (C) 2003 Sebastian Reichelt
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 2, or (at your option)
  6. any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software Foundation,
  13. Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
  14. #include "../generic.h"
  15. #include "../intrface.h"
  16. #include "data.h"
  17. #include "manip.h"
  18. #include "import/import.h"
  19. #include "export/exp_ar.h"
  20. #ifdef ENABLE_DUMP
  21. #include "dump.h"
  22. #endif /* ENABLE_DUMP */
  23. #include <stdlib.h>
  24. #include <stdio.h>
  25. #include <string.h>
  26. #ifdef __WIN32__
  27. // This definition seems to be missing in MinGW.
  28. extern void *alloca (size_t);
  29. #endif /* __WIN32__ */
  30. #define RESULT_OK 0
  31. #define RESULT_GENERAL_ERROR 1
  32. #define RESULT_EXPORT_ERROR 2
  33. #define RESULT_STRANGE_ERROR 3
  34. #ifdef TARGET_EMBEDDED
  35. extern ERROR_FUNCTION ErrorFunction;
  36. EXP_CREATE_ARCHIVE ()
  37. {
  38. const char **CurFile;
  39. #else /* !TARGET_EMBEDDED */
  40. int main (int ArgCount, const char **Args)
  41. {
  42. int CurArg;
  43. const char *DestFile = NULL;
  44. BOOLEAN NoNames = FALSE;
  45. #endif /* !TARGET_EMBEDDED */
  46. int Result = RESULT_GENERAL_ERROR;
  47. #ifdef ENABLE_DUMP
  48. BOOLEAN Dump = FALSE;
  49. #endif /* ENABLE_DUMP */
  50. ARCHIVE Archive;
  51. // Check the sizes of basic integer types.
  52. if (sizeof (I1) != 1 || sizeof (I2) != 2 || sizeof (I4) != 4 || sizeof (SI1) != 1 || sizeof (SI2) != 2 || sizeof (SI4) != 4 || sizeof (OFFSET) < sizeof (SI4))
  53. {
  54. Error (NULL, "Generic type size error!");
  55. return RESULT_STRANGE_ERROR;
  56. }
  57. // Initialize.
  58. memset (&Archive, 0, sizeof (Archive));
  59. #ifdef TARGET_EMBEDDED
  60. ErrorFunction = ErrorMessage;
  61. #endif /* TARGET_EMBEDDED */
  62. #ifdef TARGET_EMBEDDED
  63. for (CurFile = ObjectFiles; *CurFile; CurFile++)
  64. {
  65. FILE *File = fopen (*CurFile, "rb");
  66. if (File)
  67. {
  68. SIZE Size;
  69. fseek (File, 0, SEEK_END);
  70. Size = ftell (File);
  71. rewind (File);
  72. {
  73. I1 *Data = malloc (Size);
  74. if (Data)
  75. {
  76. if (fread (Data, Size, 1, File) == 1)
  77. {
  78. // Create a new object file inside the current archive.
  79. OBJECT_FILE *ObjectFile = calloc (1, sizeof (OBJECT_FILE));
  80. if (!ObjectFile)
  81. {
  82. Error (*CurFile, "Out of memory.");
  83. break;
  84. }
  85. ObjectFile->Parent = &Archive;
  86. ObjectFile->Data = Data;
  87. ObjectFile->Size = Size;
  88. ObjectFile->FileName = *CurFile;
  89. GetFileStats (*CurFile, ObjectFile->FileStats);
  90. Append (Archive.ObjectFiles, ObjectFile);
  91. // Update the statistics of the archive accordingly.
  92. if (StatFileIsNewer (ObjectFile->FileStats, Archive.FileStats))
  93. StatCopyAttributes (Archive.FileStats, ObjectFile->FileStats);
  94. // Try to import the object file's contents.
  95. ArImportObjectFile (ObjectFile);
  96. }
  97. else
  98. Error (*CurFile, "Unable to read file.");
  99. }
  100. else
  101. Error (*CurFile, "Not enough memory to load file.");
  102. }
  103. fclose (File);
  104. }
  105. else
  106. Error (*CurFile, "Unable to open file.");
  107. }
  108. #else /* !TARGET_EMBEDDED */
  109. #include "main_opt.inc"
  110. #endif /* !TARGET_EMBEDDED */
  111. {
  112. OBJECT_FILE *FirstFile = GetFirst (Archive.ObjectFiles);
  113. if (FirstFile)
  114. {
  115. // Set the destination file, in case it has not been set yet.
  116. if (!DestFile)
  117. {
  118. // alloca should not fail in any case, so we don't generate an error message.
  119. DestFile = alloca (strlen (FirstFile->FileName) + 2 + 1);
  120. if (DestFile)
  121. {
  122. strcpy ((char *) DestFile, FirstFile->FileName);
  123. strcat ((char *) DestFile, ".a");
  124. }
  125. }
  126. #ifdef ENABLE_DUMP
  127. if (Dump)
  128. DumpArchive (stdout, NULL, &Archive);
  129. #endif /* ENABLE_DUMP */
  130. // Create the symbol table information.
  131. CreateSymbolTable (&Archive);
  132. // Create other necessary information.
  133. FillExportHelpFields (&Archive);
  134. if (DestFile && (GetArchiveFileSize (&Archive) > 0))
  135. {
  136. // Write the archive.
  137. FILE *File = fopen (DestFile, "wb");
  138. if (File)
  139. {
  140. BOOLEAN ThisResult;
  141. if ((ThisResult = ExportArchiveFile (&Archive, File, NoNames)))
  142. {
  143. if (Result == RESULT_GENERAL_ERROR)
  144. Result = RESULT_OK;
  145. }
  146. else
  147. Result = RESULT_EXPORT_ERROR;
  148. fclose (File);
  149. if (!ThisResult)
  150. remove (DestFile);
  151. }
  152. else
  153. Error (DestFile, "Unable to create file.");
  154. }
  155. else
  156. Result = RESULT_EXPORT_ERROR;
  157. }
  158. else
  159. Error (DestFile, "Cannot create empty archive.");
  160. }
  161. Cleanup: ATTRIBUTE_UNUSED
  162. // Final Cleanup.
  163. FreeArchive (&Archive);
  164. return Result;
  165. }