An emulator, assembler, and disassembler for the Sega Game Gear
25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

127 lines
3.6 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 <limits.h>
  4. #include <string.h>
  5. #include "parse_util.h"
  6. #include "directives.h"
  7. /*
  8. Read in a boolean argument from the given line and store it in *result.
  9. auto_val is used if the argument's value is "auto". Return true on success
  10. and false on failure; in the latter case, *result is not modified.
  11. */
  12. bool parse_bool(bool *result, const ASMLine *line, const char *directive, bool auto_val)
  13. {
  14. size_t offset = DIRECTIVE_OFFSET(line, directive) + 1;
  15. const char *arg = line->data + offset;
  16. ssize_t len = line->length - offset;
  17. if (len <= 0 || len > 5)
  18. return false;
  19. switch (len) {
  20. case 1: // 0, 1
  21. if (*arg == '0' || *arg == '1')
  22. return (*result = *arg - '0'), true;
  23. return false;
  24. case 2: // on
  25. if (!strncmp(arg, "on", 2))
  26. return (*result = true), true;
  27. return false;
  28. case 3: // off
  29. if (!strncmp(arg, "off", 3))
  30. return (*result = false), true;
  31. return false;
  32. case 4: // true, auto
  33. if (!strncmp(arg, "true", 4))
  34. return (*result = true), true;
  35. if (!strncmp(arg, "auto", 4))
  36. return (*result = auto_val), true;
  37. return false;
  38. case 5: // false
  39. if (!strncmp(arg, "false", 5))
  40. return (*result = false), true;
  41. return false;
  42. }
  43. return false;
  44. }
  45. /*
  46. Read in a 32-bit int argument from the given line and store it in *result.
  47. Return true on success and false on failure; in the latter case, *result is
  48. not modified.
  49. */
  50. bool parse_uint32(uint32_t *result, const ASMLine *line, const char *directive)
  51. {
  52. size_t offset = DIRECTIVE_OFFSET(line, directive) + 1;
  53. const char *str = line->data + offset;
  54. const char *end = str + line->length - offset;
  55. if (end - str <= 0)
  56. return false;
  57. uint64_t value = 0;
  58. if (*str == '$') {
  59. str++;
  60. if (str == end)
  61. return false;
  62. while (str < end) {
  63. if (*str >= '0' && *str <= '9')
  64. value = value * 16 + (*str - '0');
  65. else if (*str >= 'a' && *str <= 'f')
  66. value = (value * 0x10) + 0xA + (*str - 'a');
  67. else
  68. return false;
  69. if (value > UINT32_MAX)
  70. return false;
  71. str++;
  72. }
  73. }
  74. else {
  75. while (str < end) {
  76. if (*str < '0' || *str > '9')
  77. return false;
  78. value = (value * 10) + (*str - '0');
  79. if (value > UINT32_MAX)
  80. return false;
  81. str++;
  82. }
  83. }
  84. *result = value;
  85. return true;
  86. }
  87. /*
  88. Read in a 16-bit int argument from the given line and store it in *result.
  89. Return true on success and false on failure; in the latter case, *result is
  90. not modified.
  91. */
  92. bool parse_uint16(uint16_t *result, const ASMLine *line, const char *directive)
  93. {
  94. uint32_t value;
  95. if (parse_uint32(&value, line, directive) && value <= UINT16_MAX)
  96. return (*result = value), true;
  97. return false;
  98. }
  99. /*
  100. Read in an 8-bit int argument from the given line and store it in *result.
  101. Return true on success and false on failure; in the latter case, *result is
  102. not modified.
  103. */
  104. bool parse_uint8(uint8_t *result, const ASMLine *line, const char *directive)
  105. {
  106. uint32_t value;
  107. if (parse_uint32(&value, line, directive) && value <= UINT8_MAX)
  108. return (*result = value), true;
  109. return false;
  110. }