main.cc 4.5 KB

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