main.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /*
  2. * Copyright (c) 2011 Matthew Iselin
  3. *
  4. * Permission to use, copy, modify, and distribute this software for any
  5. * purpose with or without fee is hereby granted, provided that the above
  6. * copyright notice and this permission notice appear in all copies.
  7. *
  8. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. // When VC++ compiles in debug mode, it will set _DEBUG. This sets DEBUG
  17. // in order to avoid the VC++-ism.
  18. #ifdef _DEBUG
  19. #define DEBUG
  20. #endif
  21. #include <iostream>
  22. #include <string>
  23. #include <string.h>
  24. #include "tibasic.h"
  25. #ifdef _WIN32
  26. #include "Shlwapi.h"
  27. #endif
  28. using namespace std;
  29. /// Helper function to convert a string to uppercase.
  30. char* strtoupper(char* str)
  31. {
  32. for( size_t i = 0; i < strlen( str ); i++ )
  33. {
  34. if( ! ( isupper( str[i] ) ) && isalpha( str[i] ) )
  35. str[i] = _toupper( str[i] );
  36. }
  37. return str;
  38. }
  39. /// Logs output from the build
  40. void log(LogSeverity severity, const char *out)
  41. {
  42. cout << severityToString(severity) << ": " << out << endl;
  43. }
  44. void stripExtension(const char *in, char *out, size_t len)
  45. {
  46. if(strrchr(in, '.') == NULL)
  47. return;
  48. strncpy(out, in, len);
  49. *strrchr(out, '.') = 0;
  50. }
  51. // declare global variable to set debug mode later
  52. bool verbose = false;
  53. // define help message
  54. string helpMessage = "\
  55. Usage: tibasicc [options] filename\n\
  56. Options:\n\
  57. \t-d\t\tdecompile\n\
  58. \t-o filename\tspecify output filename\n\
  59. \t-v\t\tverbose / debug mode\n\
  60. \t-h, --help\tprint this help message";
  61. int main( int argc, char* argv[] )
  62. {
  63. // check for valid number of arguments
  64. if((argc < 2) || (argv[1] == NULL))
  65. {
  66. // display error and help message when no arguments given
  67. cout << "Error: " << helpMessage << "\n";
  68. return 1;
  69. }
  70. if(!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help"))
  71. {
  72. // display help message when help flag arguments given
  73. cout << helpMessage << "\n";
  74. return 0;
  75. }
  76. Compiler compiler; Compiler *pCompiler = &compiler;
  77. string inFile, outFile;
  78. bool bDecompile = false;
  79. // Parse arguments
  80. inFile = argv[argc - 1]; // Last argument is always filename
  81. for(int i = 1; i < argc - 1; i++)
  82. {
  83. if(!strcmp(argv[i], "-o") && !outFile.length())
  84. {
  85. i++; // Next argument is filename
  86. // Output filename
  87. if(i >= argc - 1)
  88. {
  89. log(Error, "-o requires a parameter (output filename).");
  90. return 1;
  91. }
  92. outFile = argv[i];
  93. }
  94. else if(!strcmp(argv[i], "-v"))
  95. verbose = true;
  96. else if(!strcmp(argv[i], "-d"))
  97. bDecompile = true;
  98. else if(!strcmp(argv[i], "--help"))
  99. {
  100. cout << helpMessage << "\n";
  101. return 0;
  102. }
  103. else
  104. {
  105. log(Error, "Unknown option specified");
  106. return 1;
  107. }
  108. }
  109. // If no output was given, rename the input with .8xp instead of .tib and
  110. // use that as the output.
  111. if(!outFile.length())
  112. {
  113. // check for file extension and strip it if found
  114. if(strchr(inFile.c_str(), '.'))
  115. {
  116. char *tmp = new char[inFile.length()];
  117. stripExtension(inFile.c_str(), tmp, inFile.length());
  118. outFile = tmp;
  119. delete [] tmp;
  120. }
  121. else
  122. {
  123. outFile = inFile;
  124. }
  125. // set file extension for the output file
  126. if(bDecompile)
  127. outFile += ".tib";
  128. else
  129. outFile += ".8xp";
  130. // print that verbose mode is activated
  131. if(verbose)
  132. log(Info, "Verbose Mode successfully activated");
  133. }
  134. // Make sure we have tokens to work with!
  135. initialiseTokens();
  136. // Compile time!
  137. if(inFile.length() && outFile.length())
  138. {
  139. bool res = false;
  140. if(bDecompile)
  141. res = pCompiler->decompile(inFile, outFile);
  142. else
  143. res = pCompiler->compile(inFile, outFile);
  144. if(!res)
  145. {
  146. log(Error, "Compilation failed.");
  147. return 1;
  148. }
  149. }
  150. else
  151. {
  152. log(Error, "Either an input or output filename was not given.");
  153. return 1;
  154. }
  155. return 0;
  156. }