home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / gettext-0.10.24-src.tgz / tar.out / fsf / gettext / src / po.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  6KB  |  254 lines

  1. /* GNU gettext - internationalization aids
  2.    Copyright (C) 1995, 1996 Free Software Foundation, Inc.
  3.  
  4.    This file was written by Peter Miller <pmiller@agso.gov.au>
  5.  
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2, or (at your option)
  9. any later version.
  10.  
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
  19.  
  20.  
  21. #ifdef HAVE_CONFIG_H
  22. # include "config.h"
  23. #endif
  24.  
  25. #include <ctype.h>
  26. #include <stdio.h>
  27.  
  28. #ifdef HAVE_STDLIB_H
  29. # include <stdlib.h>
  30. #endif
  31.  
  32. #include "po.h"
  33. #include "po-hash.h"
  34. #include "system.h"
  35.  
  36. /* Prototypes for local functions.  */
  37. static void po_parse_brief PARAMS ((po_ty *__pop));
  38. static void po_parse_debrief PARAMS ((po_ty *__pop));
  39.  
  40. /* Methods used indirectly by po_scan.  */
  41. static void po_directive_domain PARAMS ((po_ty *__pop, char *__name));
  42. static void po_directive_message PARAMS ((po_ty *__pop, char *__msgid,
  43.                       lex_pos_ty *__msgid_pos,
  44.                       char *__msgstr,
  45.                       lex_pos_ty *__msgstr_pos));
  46. static void po_comment PARAMS ((po_ty *__pop, const char *__s));
  47. static void po_comment_dot PARAMS ((po_ty *__pop, const char *__s));
  48. static void po_comment_filepos PARAMS ((po_ty *__pop, const char *__name,
  49.                     int __line));
  50. static void po_comment_special PARAMS ((po_ty *pop, const char *s));
  51.  
  52. /* Local variables.  */
  53. static po_ty *callback_arg;
  54.  
  55.  
  56. po_ty *
  57. po_alloc (pomp)
  58.      po_method_ty *pomp;
  59. {
  60.   po_ty *pop;
  61.  
  62.   pop = xmalloc (pomp->size);
  63.   pop->method = pomp;
  64.   if (pomp->constructor)
  65.     pomp->constructor (pop);
  66.   return pop;
  67. }
  68.  
  69.  
  70. void
  71. po_free (pop)
  72.      po_ty *pop;
  73. {
  74.   if (pop->method->destructor)
  75.     pop->method->destructor (pop);
  76.   free (pop);
  77. }
  78.  
  79.  
  80. void
  81. po_scan (pop, filename)
  82.      po_ty *pop;
  83.      const char *filename;
  84. {
  85.   extern int po_gram_parse PARAMS ((void));
  86.  
  87.   /* The parse will call the po_callback_... functions (see below)
  88.      when the various directive are recognised.  The callback_arg
  89.      variable is used to tell these functions which instance is to
  90.      have the relevant method invoked.  */
  91.   callback_arg = pop;
  92.  
  93.   /* Open the file and parse it.  */
  94.   lex_open (filename);
  95.   po_parse_brief (pop);
  96.   po_gram_parse ();
  97.   po_parse_debrief (pop);
  98.   lex_close ();
  99.   callback_arg = 0;
  100. }
  101.  
  102.  
  103. static void
  104. po_parse_brief (pop)
  105.      po_ty *pop;
  106. {
  107.   if (pop->method->parse_brief)
  108.     pop->method->parse_brief (pop);
  109. }
  110.  
  111.  
  112. static void
  113. po_parse_debrief (pop)
  114.      po_ty *pop;
  115. {
  116.   if (pop->method->parse_debrief)
  117.     pop->method->parse_debrief (pop);
  118. }
  119.  
  120.  
  121. static void
  122. po_directive_domain (pop, name)
  123.      po_ty *pop;
  124.      char *name;
  125. {
  126.   if (pop->method->directive_domain)
  127.     pop->method->directive_domain (pop, name);
  128. }
  129.  
  130.  
  131. void
  132. po_callback_domain (name)
  133.      char *name;
  134. {
  135.   /* assert(callback_arg); */
  136.   po_directive_domain (callback_arg, name);
  137. }
  138.  
  139.  
  140. static void
  141. po_directive_message (pop, msgid, msgid_pos, msgstr, msgstr_pos)
  142.      po_ty *pop;
  143.      char *msgid;
  144.      lex_pos_ty *msgid_pos;
  145.      char *msgstr;
  146.      lex_pos_ty *msgstr_pos;
  147. {
  148.   if (pop->method->directive_message)
  149.     pop->method->directive_message (pop, msgid, msgid_pos, msgstr, msgstr_pos);
  150. }
  151.  
  152.  
  153. void
  154. po_callback_message (msgid, msgid_pos, msgstr, msgstr_pos)
  155.      char *msgid;
  156.      lex_pos_ty *msgid_pos;
  157.      char *msgstr;
  158.      lex_pos_ty *msgstr_pos;
  159. {
  160.   /* assert(callback_arg); */
  161.   po_directive_message (callback_arg, msgid, msgid_pos, msgstr, msgstr_pos);
  162. }
  163.  
  164.  
  165. static void
  166. po_comment_special (pop, s)
  167.      po_ty *pop;
  168.      const char *s;
  169. {
  170.   if (pop->method->comment_special != NULL)
  171.     pop->method->comment_special (pop, s);
  172. }
  173.  
  174.  
  175. static void
  176. po_comment (pop, s)
  177.      po_ty *pop;
  178.      const char *s;
  179. {
  180.   if (pop->method->comment != NULL)
  181.     pop->method->comment (pop, s);
  182. }
  183.  
  184.  
  185. static void
  186. po_comment_dot (pop, s)
  187.      po_ty *pop;
  188.      const char *s;
  189. {
  190.   if (pop->method->comment_dot != NULL)
  191.     pop->method->comment_dot (pop, s);
  192. }
  193.  
  194.  
  195. /* This function is called by po_gram_lex() whenever a comment is
  196.    seen.  It analyzes the comment to see what sort it is, and then
  197.    dispatces it to the appropriate method.  */
  198. void
  199. po_callback_comment (s)
  200.      const char *s;
  201. {
  202.   /* assert(callback_arg); */
  203.   if (*s == '.')
  204.     po_comment_dot (callback_arg, s + 1);
  205.   else if (*s == ':')
  206.     {
  207.       /* Parse the file location string.  If the parse succeeds, the
  208.      appropriate callback will be invoked.  If the parse fails,
  209.      the po_hash_parse function will return non-zero - so pretend
  210.      it was a normal comment.  */
  211.       if (po_hash (s + 1) == 0)
  212.     /* Do nothing, it is a GNU-style file pos line.  */ ;
  213.       else
  214.     po_comment (callback_arg, s + 1);
  215.     }
  216.   else if (*s == ',' || *s == '!')
  217.     /* Get all entries in the special comment line.  */
  218.     po_comment_special (callback_arg, s + 1);
  219.   else
  220.     {
  221.       /* It looks like a plain vanilla comment, but Solaris-style file
  222.      position lines do, too.  Rather than parse the lot, only look
  223.      at lines that could start with "# File..." This minimizes
  224.      memory leaks on failed parses.  If the parse succeeds, the
  225.      appropriate callback will be invoked.  */
  226.       if (s[0] == ' ' && (s[1] == 'F' || s[1] == 'f') && s[2] == 'i'
  227.       && po_hash (s) == 0)
  228.     /* Do nothing, it is a Sun-style file pos line.  */ ;
  229.       else
  230.     po_comment (callback_arg, s);
  231.     }
  232. }
  233.  
  234.  
  235. static void
  236. po_comment_filepos (pop, name, line)
  237.      po_ty *pop;
  238.      const char *name;
  239.      int line;
  240. {
  241.   if (pop->method->comment_filepos)
  242.     pop->method->comment_filepos (pop, name, line);
  243. }
  244.  
  245.  
  246. void
  247. po_callback_comment_filepos (name, line)
  248.      const char *name;
  249.      int line;
  250. {
  251.   /* assert(callback_arg); */
  252.   po_comment_filepos (callback_arg, name, line);
  253. }
  254.