An emulator, assembler, and disassembler for the Sega Game Gear
Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.
 
 
 
 
 

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