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