Back to index

glibc  2.9
ld-paper.c
Go to the documentation of this file.
00001 /* Copyright (C) 1998,1999,2000,2001,2002,2005 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
00004 
00005    This program is free software; you can redistribute it and/or modify
00006    it under the terms of the GNU General Public License as published
00007    by the Free Software Foundation; version 2 of the License, or
00008    (at your option) any later version.
00009 
00010    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013    GNU General Public License for more details.
00014 
00015    You should have received a copy of the GNU General Public License
00016    along with this program; if not, write to the Free Software Foundation,
00017    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
00018 
00019 #ifdef HAVE_CONFIG_H
00020 # include <config.h>
00021 #endif
00022 
00023 #include <error.h>
00024 #include <langinfo.h>
00025 #include <string.h>
00026 #include <sys/uio.h>
00027 
00028 #include <assert.h>
00029 
00030 #include "localedef.h"
00031 #include "localeinfo.h"
00032 #include "locfile.h"
00033 
00034 
00035 /* The real definition of the struct for the LC_PAPER locale.  */
00036 struct locale_paper_t
00037 {
00038   uint32_t height;
00039   uint32_t width;
00040 };
00041 
00042 
00043 static void
00044 paper_startup (struct linereader *lr, struct localedef_t *locale,
00045               int ignore_content)
00046 {
00047   if (!ignore_content)
00048     locale->categories[LC_PAPER].paper =
00049       (struct locale_paper_t *) xcalloc (1, sizeof (struct locale_paper_t));
00050 
00051   if (lr != NULL)
00052     {
00053       lr->translate_strings = 1;
00054       lr->return_widestr = 0;
00055     }
00056 }
00057 
00058 
00059 void
00060 paper_finish (struct localedef_t *locale, const struct charmap_t *charmap)
00061 {
00062   struct locale_paper_t *paper = locale->categories[LC_PAPER].paper;
00063   int nothing = 0;
00064 
00065   /* Now resolve copying and also handle completely missing definitions.  */
00066   if (paper == NULL)
00067     {
00068       /* First see whether we were supposed to copy.  If yes, find the
00069         actual definition.  */
00070       if (locale->copy_name[LC_PAPER] != NULL)
00071        {
00072          /* Find the copying locale.  This has to happen transitively since
00073             the locale we are copying from might also copying another one.  */
00074          struct localedef_t *from = locale;
00075 
00076          do
00077            from = find_locale (LC_PAPER, from->copy_name[LC_PAPER],
00078                             from->repertoire_name, charmap);
00079          while (from->categories[LC_PAPER].paper == NULL
00080                && from->copy_name[LC_PAPER] != NULL);
00081 
00082          paper = locale->categories[LC_PAPER].paper
00083            = from->categories[LC_PAPER].paper;
00084        }
00085 
00086       /* If there is still no definition issue an warning and create an
00087         empty one.  */
00088       if (paper == NULL)
00089        {
00090          if (! be_quiet)
00091            WITH_CUR_LOCALE (error (0, 0, _("\
00092 No definition for %s category found"), "LC_PAPER"));
00093          paper_startup (NULL, locale, 0);
00094          paper = locale->categories[LC_PAPER].paper;
00095          nothing = 1;
00096        }
00097     }
00098 
00099   if (paper->height == 0)
00100     {
00101       if (! nothing)
00102        WITH_CUR_LOCALE (error (0, 0, _("%s: field `%s' not defined"),
00103                             "LC_PAPER", "height"));
00104       /* Use as default values the values from the i18n locale.  */
00105       paper->height = 297;
00106     }
00107 
00108   if (paper->width == 0)
00109     {
00110       if (! nothing)
00111        WITH_CUR_LOCALE (error (0, 0, _("%s: field `%s' not defined"),
00112                             "LC_PAPER", "width"));
00113       /* Use as default values the values from the i18n locale.  */
00114       paper->width = 210;
00115     }
00116 }
00117 
00118 
00119 void
00120 paper_output (struct localedef_t *locale, const struct charmap_t *charmap,
00121              const char *output_path)
00122 {
00123   struct locale_paper_t *paper = locale->categories[LC_PAPER].paper;
00124   struct iovec iov[2 + _NL_ITEM_INDEX (_NL_NUM_LC_PAPER)];
00125   struct locale_file data;
00126   uint32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_PAPER)];
00127   size_t cnt = 0;
00128 
00129   data.magic = LIMAGIC (LC_PAPER);
00130   data.n = _NL_ITEM_INDEX (_NL_NUM_LC_PAPER);
00131   iov[cnt].iov_base = (void *) &data;
00132   iov[cnt].iov_len = sizeof (data);
00133   ++cnt;
00134 
00135   iov[cnt].iov_base = (void *) idx;
00136   iov[cnt].iov_len = sizeof (idx);
00137   ++cnt;
00138 
00139   idx[cnt - 2] = iov[cnt - 2].iov_len + iov[cnt - 1].iov_len;
00140   iov[cnt].iov_base = &paper->height;
00141   iov[cnt].iov_len = 4;
00142   ++cnt;
00143 
00144   idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
00145   iov[cnt].iov_base = &paper->width;
00146   iov[cnt].iov_len = 4;
00147   ++cnt;
00148 
00149   idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
00150   iov[cnt].iov_base = (void *) charmap->code_set_name;
00151   iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
00152   ++cnt;
00153 
00154   assert (cnt == 2 + _NL_ITEM_INDEX (_NL_NUM_LC_PAPER));
00155 
00156   write_locale_data (output_path, LC_PAPER, "LC_PAPER",
00157                    2 + _NL_ITEM_INDEX (_NL_NUM_LC_PAPER), iov);
00158 }
00159 
00160 
00161 /* The parser for the LC_PAPER section of the locale definition.  */
00162 void
00163 paper_read (struct linereader *ldfile, struct localedef_t *result,
00164            const struct charmap_t *charmap, const char *repertoire_name,
00165            int ignore_content)
00166 {
00167   struct locale_paper_t *paper;
00168   struct token *now;
00169   struct token *arg;
00170   enum token_t nowtok;
00171 
00172   /* The rest of the line containing `LC_PAPER' must be empty.  */
00173   lr_ignore_rest (ldfile, 1);
00174 
00175   do
00176     {
00177       now = lr_token (ldfile, charmap, result, NULL, verbose);
00178       nowtok = now->tok;
00179     }
00180   while (nowtok == tok_eol);
00181 
00182   /* If we see `copy' now we are almost done.  */
00183   if (nowtok == tok_copy)
00184     {
00185       handle_copy (ldfile, charmap, repertoire_name, result, tok_lc_paper,
00186                  LC_PAPER, "LC_PAPER", ignore_content);
00187       return;
00188     }
00189 
00190   /* Prepare the data structures.  */
00191   paper_startup (ldfile, result, ignore_content);
00192   paper = result->categories[LC_PAPER].paper;
00193 
00194   while (1)
00195     {
00196       /* Of course we don't proceed beyond the end of file.  */
00197       if (nowtok == tok_eof)
00198        break;
00199 
00200       /* Ingore empty lines.  */
00201       if (nowtok == tok_eol)
00202        {
00203          now = lr_token (ldfile, charmap, result, NULL, verbose);
00204          nowtok = now->tok;
00205          continue;
00206        }
00207 
00208       switch (nowtok)
00209        {
00210 #define INT_ELEM(cat) \
00211        case tok_##cat:                                                      \
00212          /* Ignore the rest of the line if we don't need the input of       \
00213             this line.  */                                           \
00214          if (ignore_content)                                                \
00215            {                                                         \
00216              lr_ignore_rest (ldfile, 0);                             \
00217              break;                                                  \
00218            }                                                         \
00219                                                                      \
00220          arg = lr_token (ldfile, charmap, result, NULL, verbose);           \
00221          if (arg->tok != tok_number)                                        \
00222            goto err_label;                                           \
00223          else if (paper->cat != 0)                                   \
00224            lr_error (ldfile, _("%s: field `%s' declared more than once"),    \
00225                     "LC_PAPER", #cat);                               \
00226          else if (!ignore_content)                                   \
00227            paper->cat = arg->val.num;                                       \
00228          break
00229 
00230          INT_ELEM (height);
00231          INT_ELEM (width);
00232 
00233        case tok_end:
00234          /* Next we assume `LC_PAPER'.  */
00235          arg = lr_token (ldfile, charmap, result, NULL, verbose);
00236          if (arg->tok == tok_eof)
00237            break;
00238          if (arg->tok == tok_eol)
00239            lr_error (ldfile, _("%s: incomplete `END' line"), "LC_PAPER");
00240          else if (arg->tok != tok_lc_paper)
00241            lr_error (ldfile, _("\
00242 %1$s: definition does not end with `END %1$s'"), "LC_PAPER");
00243          lr_ignore_rest (ldfile, arg->tok == tok_lc_paper);
00244          return;
00245 
00246        default:
00247        err_label:
00248          SYNTAX_ERROR (_("%s: syntax error"), "LC_PAPER");
00249        }
00250 
00251       /* Prepare for the next round.  */
00252       now = lr_token (ldfile, charmap, result, NULL, verbose);
00253       nowtok = now->tok;
00254     }
00255 
00256   /* When we come here we reached the end of the file.  */
00257   lr_error (ldfile, _("%s: premature end of file"), "LC_PAPER");
00258 }