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.
 
 
 
 
 

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