An emulator, assembler, and disassembler for the Sega Game Gear
Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 
 
 

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