main.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /****************************************************************************
  2. *
  3. * MODULE: g.parser
  4. * AUTHOR(S): Glynn Clements <glynn gclements.plus.com> (original contributor)
  5. * Bernhard Reiter <bernhard intevation.de>,
  6. * Cedric Shock <cedricgrass shockfamily.net>,
  7. * Hamish Bowman <hamish_b yahoo.com>,
  8. * Paul Kelly <paul-grass stjohnspoint.co.uk>,
  9. * Radim Blazek <radim.blazek gmail.com>
  10. * PURPOSE:
  11. * COPYRIGHT: (C) 2001-2007, 2010-2011 by the GRASS Development Team
  12. *
  13. * This program is free software under the GNU General Public
  14. * License (>=v2). Read the file COPYING that comes with GRASS
  15. * for details.
  16. *
  17. *****************************************************************************/
  18. #include <stdlib.h>
  19. #include <unistd.h>
  20. #include <string.h>
  21. #include <grass/glocale.h>
  22. #include "proto.h"
  23. int translate_output;
  24. int main(int argc, char *argv[])
  25. {
  26. char *progname;
  27. struct context ctx;
  28. const char *filename;
  29. int standard_output;
  30. int separator_nul;
  31. progname = argv[0];
  32. ctx.module = NULL;
  33. ctx.option = NULL;
  34. ctx.flag = NULL;
  35. ctx.first_option = NULL;
  36. ctx.first_flag = NULL;
  37. ctx.state = S_TOPLEVEL;
  38. standard_output = translate_output = separator_nul = FALSE;
  39. /* Detect request to get strings to translate from a file */
  40. /* It comes BEFORE the filename to completely avoid confusion with parser.c behaviours */
  41. if (argc >= 2 && (strcmp(argv[1], "-t") == 0)) {
  42. /* Turn on translation output */
  43. translate_output = TRUE;
  44. argv++, argc--;
  45. }
  46. if (argc >= 2 && (strcmp(argv[1], "-s") == 0)) {
  47. /* write to stdout rather than re-invoking */
  48. standard_output = TRUE;
  49. argv++, argc--;
  50. }
  51. if (argc >= 2 && (strcmp(argv[1], "-n") == 0)) {
  52. /* write to stdout with NUL as separator */
  53. standard_output = TRUE;
  54. separator_nul = TRUE;
  55. argv++, argc--;
  56. }
  57. if ((argc < 2) || ((strcmp(argv[1], "help") == 0) ||
  58. (strcmp(argv[1], "-help") == 0) ||
  59. (strcmp(argv[1], "--help") == 0))) {
  60. fprintf(stderr, "%s: %s [-t] [-s] [-n] <filename> [<argument> ...]\n",
  61. _("Usage"), progname);
  62. exit(EXIT_FAILURE);
  63. }
  64. filename = argv[1];
  65. argv++, argc--;
  66. G_debug(2, "filename = %s", filename);
  67. ctx.fp = fopen(filename, "r");
  68. if (!ctx.fp) {
  69. perror(_("Unable to open script file"));
  70. exit(EXIT_FAILURE);
  71. }
  72. G_gisinit((char *)filename);
  73. for (ctx.line = 1;; ctx.line++) {
  74. char buff[4096];
  75. char *cmd, *arg;
  76. size_t line_size;
  77. if (!fgets(buff, sizeof(buff), ctx.fp))
  78. break;
  79. arg = strchr(buff, '\n');
  80. if (!arg) {
  81. fprintf(stderr, _("Line too long or missing newline at line %d\n"),
  82. ctx.line);
  83. exit(EXIT_FAILURE);
  84. }
  85. *arg = '\0';
  86. line_size = strlen(buff);
  87. if (line_size > 2 && buff[0] == '#') {
  88. if (buff[1] == '%')
  89. cmd = buff + 2;
  90. else if (line_size > 3 && buff[1] == ' ' && buff[2] == '%')
  91. cmd = buff + 3;
  92. else
  93. continue;
  94. }
  95. else {
  96. continue;
  97. }
  98. G_chop(cmd);
  99. arg = strchr(cmd, ':');
  100. if (arg) {
  101. *(arg++) = '\0';
  102. G_strip(cmd);
  103. G_strip(arg);
  104. }
  105. switch (ctx.state) {
  106. case S_TOPLEVEL:
  107. parse_toplevel(&ctx, cmd);
  108. break;
  109. case S_MODULE:
  110. parse_module(&ctx, cmd, arg);
  111. break;
  112. case S_FLAG:
  113. parse_flag(&ctx, cmd, arg);
  114. break;
  115. case S_OPTION:
  116. parse_option(&ctx, cmd, arg);
  117. break;
  118. case S_RULES:
  119. parse_rule(&ctx, cmd, arg);
  120. break;
  121. }
  122. }
  123. if (fclose(ctx.fp) != 0) {
  124. perror(_("Error closing script file"));
  125. exit(EXIT_FAILURE);
  126. }
  127. /* Stop here successfully if all that was desired was output of text to translate */
  128. /* Continuing from here would get argc and argv all wrong in G_parser. */
  129. if (translate_output)
  130. exit(EXIT_SUCCESS);
  131. if (G_parser(argc, argv))
  132. exit(EXIT_FAILURE);
  133. return standard_output
  134. ? print_options(&ctx, separator_nul ? '\0' : '\n')
  135. : reinvoke_script(&ctx, filename);
  136. }