main.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  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. */
  112. if(!outFile.length())
  113. {
  114. /* check for file extension and strip it if found */
  115. if(strchr(inFile.c_str(), '.'))
  116. {
  117. char *tmp = new char[inFile.length()];
  118. stripExtension(inFile.c_str(), tmp, inFile.length());
  119. outFile = tmp;
  120. delete [] tmp;
  121. }
  122. else
  123. {
  124. outFile = inFile;
  125. }
  126. /* set file extension for the output file */
  127. if(bDecompile)
  128. outFile += ".tib";
  129. else
  130. outFile += ".8xp";
  131. /* print that verbose mode is activated */
  132. if(verbose)
  133. log(Info, "Verbose Mode successfully activated");
  134. }
  135. /* Make sure we have tokens to work with! */
  136. initialiseTokens();
  137. /* Compile time! */
  138. if(inFile.length() && outFile.length())
  139. {
  140. bool res = false;
  141. if(bDecompile)
  142. res = pCompiler->decompile(inFile, outFile);
  143. else
  144. res = pCompiler->compile(inFile, outFile);
  145. if(!res)
  146. {
  147. log(Error, "Compilation failed.");
  148. return 1;
  149. }
  150. }
  151. else
  152. {
  153. log(Error, "Either an input or output filename was not given.");
  154. return 1;
  155. }
  156. return 0;
  157. }