An emulator, assembler, and disassembler for the Sega Game Gear
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.
 
 
 
 
 

125 řádky
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. const char *str = line->data + (DIRECTIVE_OFFSET(line, directive) + 1);
  52. const char *end = str + (line->length - (DIRECTIVE_OFFSET(line, directive) + 1));
  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(uint16_t *result, const ASMLine *line, const char *directive)
  91. {
  92. uint32_t value;
  93. if (parse_uint32(&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(uint8_t *result, const ASMLine *line, const char *directive)
  103. {
  104. uint32_t value;
  105. if (parse_uint32(&value, line, directive) && value <= UINT8_MAX)
  106. return (*result = value), true;
  107. return false;
  108. }