parse.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. #include <string.h>
  2. #include <stdlib.h>
  3. #include "proto.h"
  4. #include <grass/glocale.h>
  5. static char *xstrdup(const char *arg)
  6. {
  7. return (G_strcasecmp(arg, "{NULL}") == 0)
  8. ? NULL : strdup(arg);
  9. }
  10. int parse_boolean(struct context *ctx, const char *arg)
  11. {
  12. if (G_strcasecmp(arg, "yes") == 0)
  13. return YES;
  14. if (G_strcasecmp(arg, "no") == 0)
  15. return NO;
  16. fprintf(stderr, _("Unknown boolean value \"%s\" at line %d\n"),
  17. arg, ctx->line);
  18. return NO;
  19. }
  20. void parse_toplevel(struct context *ctx, const char *cmd)
  21. {
  22. char **tokens;
  23. if (G_strcasecmp(cmd, "module") == 0) {
  24. ctx->state = S_MODULE;
  25. ctx->module = G_define_module();
  26. return;
  27. }
  28. if (G_strcasecmp(cmd, "flag") == 0) {
  29. ctx->state = S_FLAG;
  30. ctx->flag = G_define_flag();
  31. if (!ctx->first_flag)
  32. ctx->first_flag = ctx->flag;
  33. return;
  34. }
  35. if (G_strncasecmp(cmd, "option", strlen("option")) == 0) {
  36. ctx->state = S_OPTION;
  37. tokens = G_tokenize(cmd, " ");
  38. if (G_number_of_tokens(tokens) > 1) {
  39. /* standard option */
  40. ctx->option = define_standard_option(tokens[1]);
  41. }
  42. else {
  43. ctx->option = G_define_option();
  44. }
  45. if (!ctx->first_option)
  46. ctx->first_option = ctx->option;
  47. G_free_tokens(tokens);
  48. return;
  49. }
  50. fprintf(stderr, _("Unknown command \"%s\" at line %d\n"), cmd, ctx->line);
  51. }
  52. void parse_module(struct context *ctx, const char *cmd, const char *arg)
  53. {
  54. /* Label and description can be internationalized */
  55. if (G_strcasecmp(cmd, "label") == 0) {
  56. ctx->module->label = translate(xstrdup(arg));
  57. return;
  58. }
  59. if (G_strcasecmp(cmd, "description") == 0) {
  60. ctx->module->description = translate(xstrdup(arg));
  61. return;
  62. }
  63. if (G_strcasecmp(cmd, "keywords") == 0) {
  64. G_add_keyword(translate(xstrdup(arg)));
  65. return;
  66. }
  67. if (G_strcasecmp(cmd, "overwrite") == 0) {
  68. ctx->module->overwrite = parse_boolean(ctx, arg);
  69. return;
  70. }
  71. if (G_strcasecmp(cmd, "end") == 0) {
  72. ctx->state = S_TOPLEVEL;
  73. return;
  74. }
  75. fprintf(stderr, _("Unknown module parameter \"%s\" at line %d\n"),
  76. cmd, ctx->line);
  77. }
  78. void parse_flag(struct context *ctx, const char *cmd, const char *arg)
  79. {
  80. if (G_strcasecmp(cmd, "key") == 0) {
  81. ctx->flag->key = arg[0];
  82. return;
  83. }
  84. if (G_strcasecmp(cmd, "suppress_required") == 0) {
  85. ctx->flag->suppress_required = parse_boolean(ctx, arg);
  86. return;
  87. }
  88. /* Label, description, and guisection can all be internationalized */
  89. if (G_strcasecmp(cmd, "label") == 0) {
  90. ctx->flag->label = translate(xstrdup(arg));
  91. return;
  92. }
  93. if (G_strcasecmp(cmd, "description") == 0) {
  94. ctx->flag->description = translate(xstrdup(arg));
  95. return;
  96. }
  97. if (G_strcasecmp(cmd, "guisection") == 0) {
  98. ctx->flag->guisection = translate(xstrdup(arg));
  99. return;
  100. }
  101. if (G_strcasecmp(cmd, "end") == 0) {
  102. ctx->state = S_TOPLEVEL;
  103. return;
  104. }
  105. fprintf(stderr, _("Unknown flag parameter \"%s\" at line %d\n"),
  106. cmd, ctx->line);
  107. }
  108. int parse_type(struct context *ctx, const char *arg)
  109. {
  110. if (G_strcasecmp(arg, "integer") == 0)
  111. return TYPE_INTEGER;
  112. if (G_strcasecmp(arg, "double") == 0)
  113. return TYPE_DOUBLE;
  114. if (G_strcasecmp(arg, "string") == 0)
  115. return TYPE_STRING;
  116. fprintf(stderr, _("Unknown type \"%s\" at line %d\n"), arg, ctx->line);
  117. return TYPE_STRING;
  118. }
  119. void parse_option(struct context *ctx, const char *cmd, const char *arg)
  120. {
  121. if (G_strcasecmp(cmd, "key") == 0) {
  122. ctx->option->key = xstrdup(arg);
  123. return;
  124. }
  125. if (G_strcasecmp(cmd, "type") == 0) {
  126. ctx->option->type = parse_type(ctx, arg);
  127. return;
  128. }
  129. if (G_strcasecmp(cmd, "required") == 0) {
  130. ctx->option->required = parse_boolean(ctx, arg);
  131. return;
  132. }
  133. if (G_strcasecmp(cmd, "multiple") == 0) {
  134. ctx->option->multiple = parse_boolean(ctx, arg);
  135. return;
  136. }
  137. if (G_strcasecmp(cmd, "options") == 0) {
  138. ctx->option->options = xstrdup(arg);
  139. return;
  140. }
  141. if (G_strcasecmp(cmd, "key_desc") == 0) {
  142. ctx->option->key_desc = xstrdup(arg);
  143. return;
  144. }
  145. /* Label, description, descriptions, and guisection can all be internationalized */
  146. if (G_strcasecmp(cmd, "label") == 0) {
  147. ctx->option->label = translate(xstrdup(arg));
  148. return;
  149. }
  150. if (G_strcasecmp(cmd, "description") == 0) {
  151. ctx->option->description = translate(xstrdup(arg));
  152. return;
  153. }
  154. if (G_strcasecmp(cmd, "descriptions") == 0) {
  155. ctx->option->descriptions = translate(xstrdup(arg));
  156. return;
  157. }
  158. if (G_strcasecmp(cmd, "answer") == 0) {
  159. ctx->option->answer = xstrdup(arg);
  160. return;
  161. }
  162. if (G_strcasecmp(cmd, "gisprompt") == 0) {
  163. ctx->option->gisprompt = xstrdup(arg);
  164. return;
  165. }
  166. if (G_strcasecmp(cmd, "guisection") == 0) {
  167. ctx->option->guisection = translate(xstrdup(arg));
  168. return;
  169. }
  170. if (G_strcasecmp(cmd, "guidependency") == 0) {
  171. ctx->option->guidependency = translate(xstrdup(arg));
  172. return;
  173. }
  174. if (G_strcasecmp(cmd, "end") == 0) {
  175. ctx->state = S_TOPLEVEL;
  176. return;
  177. }
  178. fprintf(stderr, _("Unknown option parameter \"%s\" at line %d\n"),
  179. cmd, ctx->line);
  180. }
  181. int print_options(const struct context *ctx)
  182. {
  183. struct Option *option;
  184. struct Flag *flag;
  185. const char *overwrite = getenv("GRASS_OVERWRITE");
  186. const char *verbose = getenv("GRASS_VERBOSE");
  187. printf("@ARGS_PARSED@\n");
  188. if (overwrite)
  189. printf("GRASS_OVERWRITE=%s\n", overwrite);
  190. if (verbose)
  191. printf("GRASS_VERBOSE=%s\n", verbose);
  192. for (flag = ctx->first_flag; flag; flag = flag->next_flag)
  193. printf("flag_%c=%d\n", flag->key, flag->answer ? 1 : 0);
  194. for (option = ctx->first_option; option; option = option->next_opt)
  195. printf("opt_%s=%s\n", option->key,
  196. option->answer ? option->answer : "");
  197. return EXIT_SUCCESS;
  198. }