main.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  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. if (!fgets(buff, sizeof(buff), ctx.fp))
  77. break;
  78. arg = strchr(buff, '\n');
  79. if (!arg) {
  80. fprintf(stderr, _("Line too long or missing newline at line %d\n"),
  81. ctx.line);
  82. exit(EXIT_FAILURE);
  83. }
  84. *arg = '\0';
  85. if (buff[0] != '#' || buff[1] != '%')
  86. continue;
  87. cmd = buff + 2;
  88. G_chop(cmd);
  89. arg = strchr(cmd, ':');
  90. if (arg) {
  91. *(arg++) = '\0';
  92. G_strip(cmd);
  93. G_strip(arg);
  94. }
  95. switch (ctx.state) {
  96. case S_TOPLEVEL:
  97. parse_toplevel(&ctx, cmd);
  98. break;
  99. case S_MODULE:
  100. parse_module(&ctx, cmd, arg);
  101. break;
  102. case S_FLAG:
  103. parse_flag(&ctx, cmd, arg);
  104. break;
  105. case S_OPTION:
  106. parse_option(&ctx, cmd, arg);
  107. break;
  108. case S_RULES:
  109. parse_rule(&ctx, cmd, arg);
  110. break;
  111. }
  112. }
  113. if (fclose(ctx.fp) != 0) {
  114. perror(_("Error closing script file"));
  115. exit(EXIT_FAILURE);
  116. }
  117. /* Stop here successfully if all that was desired was output of text to translate */
  118. /* Continuing from here would get argc and argv all wrong in G_parser. */
  119. if (translate_output)
  120. exit(EXIT_SUCCESS);
  121. if (G_parser(argc, argv))
  122. exit(EXIT_FAILURE);
  123. return standard_output
  124. ? print_options(&ctx, separator_nul ? '\0' : '\n')
  125. : reinvoke_script(&ctx, filename);
  126. }