An emulator, assembler, and disassembler for the Sega Game Gear
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 

156 linhas
4.2 KiB

  1. /* Copyright (C) 2014-2015 Ben Kurtovic <ben.kurtovic@gmail.com>
  2. Released under the terms of the MIT License. See LICENSE for details. */
  3. #include <stdlib.h>
  4. #include "errors.h"
  5. #include "state.h"
  6. #include "../assembler.h"
  7. #include "../logging.h"
  8. #define ERROR_TYPE(err_info) (asm_error_types[err_info->type])
  9. #define ERROR_DESC(err_info) (asm_error_descs[err_info->desc])
  10. /* Error strings */
  11. static const char *asm_error_types[] = {
  12. "include directive", // ET_INCLUDE
  13. "preprocessor", // ET_PREPROC
  14. "memory layout", // ET_LAYOUT
  15. "instruction parser" // ET_PARSER
  16. };
  17. static const char *asm_error_descs[] = {
  18. "missing or invalid argument", // ED_INC_BAD_ARG
  19. "infinite recursion detected", // ED_INC_RECURSION
  20. "couldn't read included file", // ED_INC_FILE_READ
  21. "unknown directive", // ED_PP_UNKNOWN
  22. "multiple values for directive", // ED_PP_DUPLICATE
  23. "missing argument for directive", // ED_PP_NO_ARG
  24. "invalid argument for directive", // ED_PP_BAD_ARG
  25. "directive argument out of range", // ED_PP_ARG_RANGE
  26. "header offset exceeds given ROM size", // ED_LYT_HEADER_RANGE
  27. "declared ROM size in header exceeds actual size", // ED_LYT_DECLARE_RANGE
  28. "duplicate definitions for label", // ED_LYT_DUPE_LABELS
  29. "location is out of bounds for the ROM size", // ED_LYT_BOUNDS
  30. "location overlaps with instruction or data", // ED_LYT_OVERLAP
  31. "location overlaps with ROM header", // ED_LYT_OVERLAP_HEAD
  32. "syntax error" // ED_PARSE_SYNTAX
  33. };
  34. /* Internal structs */
  35. struct ASMErrorLine {
  36. char *data;
  37. size_t length;
  38. size_t lineno;
  39. char *filename;
  40. struct ASMErrorLine *next;
  41. };
  42. typedef struct ASMErrorLine ASMErrorLine;
  43. struct ErrorInfo {
  44. ASMErrorType type;
  45. ASMErrorDesc desc;
  46. ASMErrorLine *line;
  47. };
  48. /*
  49. Create an ASMErrorLine object from an ASMLine.
  50. */
  51. static ASMErrorLine* create_error_line(const ASMLine *line)
  52. {
  53. ASMErrorLine *el = malloc(sizeof(ASMErrorLine));
  54. if (!el)
  55. OUT_OF_MEMORY()
  56. const char *source = line->original->data;
  57. size_t length = line->original->length;
  58. if (!(el->data = malloc(sizeof(char) * length)))
  59. OUT_OF_MEMORY()
  60. // Ignore spaces at beginning:
  61. while (length > 0 && (*source == ' ' || *source == '\t'))
  62. source++, length--;
  63. memcpy(el->data, source, length);
  64. el->length = length;
  65. el->lineno = line->original->lineno;
  66. el->filename = strdup(line->filename);
  67. if (!el->filename)
  68. OUT_OF_MEMORY()
  69. el->next = NULL;
  70. return el;
  71. }
  72. /*
  73. Create an ErrorInfo object describing a particular error.
  74. The ErrorInfo object can be printed with error_info_print(), and must be
  75. freed when done with error_info_destroy().
  76. This function never fails (OOM triggers an exit()); the caller can be
  77. confident the returned object is valid.
  78. */
  79. ErrorInfo* error_info_create(
  80. const ASMLine *line, ASMErrorType err_type, ASMErrorDesc err_desc)
  81. {
  82. ErrorInfo *einfo = malloc(sizeof(ErrorInfo));
  83. if (!einfo)
  84. OUT_OF_MEMORY()
  85. einfo->type = err_type;
  86. einfo->desc = err_desc;
  87. einfo->line = line ? create_error_line(line) : NULL;
  88. return einfo;
  89. }
  90. /*
  91. Add an ASMLine to an ErrorInfo object, as part of a file trace.
  92. */
  93. void error_info_append(ErrorInfo *einfo, const ASMLine *line)
  94. {
  95. ASMErrorLine* el = create_error_line(line);
  96. el->next = einfo->line;
  97. einfo->line = el;
  98. }
  99. /*
  100. Print an ErrorInfo object returned by assemble() to the given stream.
  101. */
  102. void error_info_print(const ErrorInfo *einfo, FILE *file)
  103. {
  104. ASMErrorLine *line = einfo->line;
  105. fprintf(file, "error: %s: %s\n", ERROR_TYPE(einfo), ERROR_DESC(einfo));
  106. while (line) {
  107. fprintf(file, "%s:%zu:\n", line->filename, line->lineno);
  108. fprintf(file, " %.*s\n", (int) line->length, line->data);
  109. line = line->next;
  110. }
  111. }
  112. /*
  113. Destroy an ErrorInfo object created by assemble().
  114. */
  115. void error_info_destroy(ErrorInfo *error_info)
  116. {
  117. if (!error_info)
  118. return;
  119. ASMErrorLine *line = error_info->line, *temp;
  120. while (line) {
  121. temp = line->next;
  122. free(line->data);
  123. free(line->filename);
  124. free(line);
  125. line = temp;
  126. }
  127. free(error_info);
  128. }