An emulator, assembler, and disassembler for the Sega Game Gear
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 
 

125 lignes
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. }