llpkgc.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. file LICENSE.rst or https://cmake.org/licensing for details. */
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include "llpkgc.h"
  6. #define CALLBACK_MAYBE(PARSER, NAME) \
  7. do { \
  8. const llpkgc_settings_t* settings; \
  9. settings = (const llpkgc_settings_t*) (PARSER)->settings; \
  10. if(settings == NULL || settings->NAME == NULL) { \
  11. err = 0; \
  12. break; \
  13. } \
  14. err = settings->NAME((PARSER)); \
  15. } while(0)
  16. #define SPAN_CALLBACK_MAYBE(PARSER, NAME, START, LEN) \
  17. do { \
  18. const llpkgc_settings_t* settings; \
  19. settings = (const llpkgc_settings_t*) (PARSER)->settings; \
  20. if(settings == NULL || settings->NAME == NULL) { \
  21. err = 0; \
  22. break; \
  23. } \
  24. err = settings->NAME((PARSER), (START), (LEN)); \
  25. if(err == -1) { \
  26. err = PCE_USER; \
  27. llpkgc_set_error_reason((PARSER), "Span callback error in " #NAME); \
  28. } \
  29. } while(0)
  30. void llpkgc_init(llpkgc_t* parser, const llpkgc_settings_t* settings) {
  31. llpkgc__internal_init(parser);
  32. parser->settings = (void*) settings;
  33. }
  34. void llpkgc_reset(llpkgc_t* parser) {
  35. llpkgc_settings_t* settings = parser->settings;
  36. void* data = parser->data;
  37. llpkgc__internal_init(parser);
  38. parser->settings = settings;
  39. parser->data = data;
  40. }
  41. void llpkgc_settings_init(llpkgc_settings_t* settings) {
  42. memset(settings, 0, sizeof(*settings));
  43. }
  44. llpkgc_errno_t llpkgc_execute(llpkgc_t* parser, const char* data, size_t len) {
  45. return llpkgc__internal_execute(parser, data, data + len);
  46. }
  47. llpkgc_errno_t llpkgc_finish(llpkgc_t* parser) {
  48. if(parser->error != 0)
  49. return parser->error;
  50. int err;
  51. // ToDo: Better handling of user callback errors here
  52. if(parser->unfinished_ == 1) {
  53. parser->reason = "Invalid EOF state";
  54. parser->error = PCE_UNFINISHED;
  55. return PCE_UNFINISHED;
  56. } else if(parser->unfinished_ == 2) {
  57. CALLBACK_MAYBE(parser, on_value_literal_complete);
  58. if(err != PCE_OK) {
  59. parser->error = err;
  60. return err;
  61. }
  62. CALLBACK_MAYBE(parser, on_value_complete);
  63. if(err != PCE_OK) {
  64. parser->error = err;
  65. return err;
  66. }
  67. } else if(parser->unfinished_ == 3) {
  68. CALLBACK_MAYBE(parser, on_value_complete);
  69. if(err != PCE_OK) {
  70. parser->error = err;
  71. return err;
  72. }
  73. }
  74. CALLBACK_MAYBE(parser, on_pkgc_complete);
  75. return err;
  76. }
  77. void llpkgc_pause(llpkgc_t* parser) {
  78. if(parser->error != PCE_OK) {
  79. return;
  80. }
  81. parser->error = PCE_PAUSED;
  82. parser->reason = "Paused";
  83. }
  84. void llpkgc_resume(llpkgc_t* parser) {
  85. if(parser->error != PCE_PAUSED) {
  86. return;
  87. }
  88. parser->error = 0;
  89. }
  90. llpkgc_errno_t llpkgc_get_errno(const llpkgc_t* parser) {
  91. return parser->error;
  92. }
  93. const char* llpkgc_get_error_reason(const llpkgc_t* parser) {
  94. return parser->reason;
  95. }
  96. void llpkgc_set_error_reason(llpkgc_t* parser, const char* reason) {
  97. parser->reason = reason;
  98. }
  99. const char* llpkgc_get_error_pos(const llpkgc_t* parser) {
  100. return parser->error_pos;
  101. }
  102. const char* llpkgc_errno_name(llpkgc_errno_t err) {
  103. switch(err) {
  104. case PCE_OK:
  105. return "PCE_OK";
  106. case PCE_INTERNAL:
  107. return "PCE_INTERNAL";
  108. case PCE_PAUSED:
  109. return "PCE_PAUSED";
  110. case PCE_USER:
  111. return "PCE_USER";
  112. case PCE_UNFINISHED:
  113. return "PCE_UNFINISHED";
  114. }
  115. return "INVALID_ERRNO";
  116. }
  117. int llpkgc__line_begin(llpkgc_t* s, const char* p, const char* endp) {
  118. int err;
  119. s->unfinished_ = 1;
  120. CALLBACK_MAYBE(s, on_line_begin);
  121. return err;
  122. }
  123. int llpkgc__key_span(llpkgc_t* s, const char* p, const char* endp) {
  124. int err;
  125. SPAN_CALLBACK_MAYBE(s, on_key, p, endp - p);
  126. return err;
  127. }
  128. int llpkgc__keyword_complete(llpkgc_t* s, const char* p, const char* endp) {
  129. int err;
  130. s->unfinished_ = 3;
  131. CALLBACK_MAYBE(s, on_keyword_complete);
  132. return err;
  133. }
  134. int llpkgc__variable_complete(llpkgc_t* s, const char* p, const char* endp) {
  135. int err;
  136. s->unfinished_ = 3;
  137. CALLBACK_MAYBE(s, on_variable_complete);
  138. return err;
  139. }
  140. int llpkgc__vallit_span(llpkgc_t* s, const char* p, const char* endp) {
  141. int err;
  142. if(s->escaped_) {
  143. --endp;
  144. s->escaped_ = 0;
  145. }
  146. s->unfinished_ = 2;
  147. SPAN_CALLBACK_MAYBE(s, on_value_literal, p, endp - p);
  148. return err;
  149. }
  150. int llpkgc__vallit_complete(llpkgc_t* s, const char* p, const char* endp) {
  151. int err;
  152. s->unfinished_ = 3;
  153. CALLBACK_MAYBE(s, on_value_literal_complete);
  154. return err;
  155. }
  156. int llpkgc__valvar_span(llpkgc_t* s, const char* p, const char* endp) {
  157. int err;
  158. s->unfinished_ = 1;
  159. SPAN_CALLBACK_MAYBE(s, on_value_variable, p, endp - p);
  160. return err;
  161. }
  162. int llpkgc__valvar_complete(llpkgc_t* s, const char* p, const char* endp) {
  163. int err;
  164. s->unfinished_ = 3;
  165. CALLBACK_MAYBE(s, on_value_variable_complete);
  166. return err;
  167. }
  168. int llpkgc__value_complete(llpkgc_t* s, const char* p, const char* endp) {
  169. int err;
  170. s->unfinished_ = 0;
  171. CALLBACK_MAYBE(s, on_value_complete);
  172. return err;
  173. }