/[man-db]/man-db/src/encodings.c
ViewVC logotype

Diff of /man-db/src/encodings.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.5 by cjwatson, Sun Sep 7 22:10:25 2003 UTC revision 1.6 by cjwatson, Sun Sep 14 15:24:25 2003 UTC
# Line 72  Line 72 
72   * distribution; send me updates for languages I've missed.   * distribution; send me updates for languages I've missed.
73   *   *
74   * Explicit encodings in the directory name (e.g. de_DE.UTF-8) override this   * Explicit encodings in the directory name (e.g. de_DE.UTF-8) override this
75   * table. TODO: Implement this.   * table.
76   */   */
77  static struct {  struct directory_entry {
78          const char *lang_dir;          const char *lang_dir;
79          const char *source_encoding;          const char *source_encoding;
80          const char *standard_output_encoding;          const char *standard_output_encoding;
81  } directory_table[] = {  };
82    
83    static struct directory_entry directory_table[] = {
84          { "C",          "ISO-8859-1",   "ANSI_X3.4-1968"        }, /* English */          { "C",          "ISO-8859-1",   "ANSI_X3.4-1968"        }, /* English */
85          { "POSIX",      "ISO-8859-1",   "ANSI_X3.4-1968"        }, /* English */          { "POSIX",      "ISO-8859-1",   "ANSI_X3.4-1968"        }, /* English */
86          { "da",         "ISO-8859-1",   "ISO-8859-1"            }, /* Danish */          { "da",         "ISO-8859-1",   "ISO-8859-1"            }, /* Danish */
# Line 107  static struct { Line 109  static struct {
109          { "ru",         "KOI8-R",       "KOI8-R"                }, /* Russian */          { "ru",         "KOI8-R",       "KOI8-R"                }, /* Russian */
110  #endif /* MULTIBYTE_GROFF */  #endif /* MULTIBYTE_GROFF */
111    
112          { NULL,         NULL,           "NULL"                  } };          { NULL,         NULL,           "NULL"                  }
113    };
114    
115  /* The default groff terminal output device to be used is determined based  /* The default groff terminal output device to be used is determined based
116   * on nl_langinfo(CODESET), which returns the character set used by the   * on nl_langinfo(CODESET), which returns the character set used by the
117   * current locale.   * current locale.
118   */   */
119  static struct {  struct charset_entry {
120          const char *locale_charset;          const char *locale_charset;
121          const char *default_device;          const char *default_device;
122  } charset_table[] = {  };
123    
124    static struct charset_entry charset_table[] = {
125          { "ANSI_X3.4-1968",     "ascii"         },          { "ANSI_X3.4-1968",     "ascii"         },
126          { "ISO-8859-1",         "latin1"        },          { "ISO-8859-1",         "latin1"        },
127          { "UTF-8",              "utf8"          },          { "UTF-8",              "utf8"          },
# Line 125  static struct { Line 130  static struct {
130          { "EUC-JP",             "nippon"        },          { "EUC-JP",             "nippon"        },
131  #endif /* MULTIBYTE_GROFF */  #endif /* MULTIBYTE_GROFF */
132    
133          { NULL,                 NULL            } };          { NULL,                 NULL            }
134    };
135    
136  static const char *fallback_default_device =  static const char *fallback_default_device =
137  #ifdef MULTIBYTE_GROFF  #ifdef MULTIBYTE_GROFF
# Line 142  static const char *fallback_default_devi Line 148  static const char *fallback_default_devi
148   * straight through so is (probably ...) encoding-agnostic. If this encoding   * straight through so is (probably ...) encoding-agnostic. If this encoding
149   * does not match the source encoding, an iconv pipe is used (if available)   * does not match the source encoding, an iconv pipe is used (if available)
150   * to perform recoding.   * to perform recoding.
  *  
  * Setting less_charset to latin1 tells the less pager that characters  
  * between 0xA0 and 0xFF are displayable, not that its input is encoded in  
  * ISO-8859-1. TODO: Perhaps using LESSCHARDEF would be better.  
151   */   */
152  static struct {  struct device_entry {
153          const char *roff_device;          const char *roff_device;
154          const char *roff_encoding;          const char *roff_encoding;
155          const char *less_charset;          const char *output_encoding;
156  } device_table[] = {  };
157          { "ascii",      "ISO-8859-1",   "ascii"         },  
158          { "latin1",     "ISO-8859-1",   "latin1"        },  static struct device_entry device_table[] = {
159          { "utf8",       "ISO-8859-1",   "utf-8"         },          { "ascii",      "ISO-8859-1",   "ANSI_X3.4-1968"        },
160            { "latin1",     "ISO-8859-1",   "ISO-8859-1"            },
161            { "utf8",       "ISO-8859-1",   "UTF-8"                 },
162    
163  #ifdef MULTIBYTE_GROFF  #ifdef MULTIBYTE_GROFF
164          { "ascii8",     NULL,           "latin1"        },          { "ascii8",     NULL,           NULL                    },
165          { "nippon",     "EUC-JP",       "ja"            },          { "nippon",     "EUC-JP",       "EUC-JP"                },
166  #endif /* MULTIBYTE_GROFF */  #endif /* MULTIBYTE_GROFF */
167    
168          { NULL,         NULL,           NULL            } };          { NULL,         NULL,           NULL                    }
169    };
170    
171  static const char *fallback_roff_encoding = "ISO-8859-1";  static const char *fallback_roff_encoding = "ISO-8859-1";
172  static const char *fallback_less_charset = "latin1";  
173    /* Setting less_charset to iso8859 tells the less pager that characters
174     * between 0xA0 and 0xFF are displayable, not that its input is encoded in
175     * ISO-8859-*. TODO: Perhaps using LESSCHARDEF would be better.
176     */
177    struct less_charset_entry {
178            const char *locale_charset;
179            const char *less_charset;
180    };
181    
182    static struct less_charset_entry less_charset_table[] = {
183            { "ANSI_X3.4-1968",     "ascii"         },
184            { "ISO-8859-1",         "iso8859"       },
185            { "UTF-8",              "utf-8"         },
186    
187    #ifdef MULTIBYTE_GROFF
188            { "EUC-JP",             "ja"            },
189            { "KOI8-R",             "koi8-r"        },
190    #endif /* MULTIBYTE_GROFF */
191    
192            { NULL,                 NULL            }
193    };
194    
195    static const char *fallback_less_charset = "iso8859";
196    
197    
198  /* Return the assumed encoding of the source man page, based on the  /* Return the assumed encoding of the source man page, based on the
# Line 275  const char *get_locale_charset (void) Line 303  const char *get_locale_charset (void)
303                  return NULL;                  return NULL;
304  }  }
305    
306    /* Can we take this input encoding and produce this output encoding, perhaps
307     * with the help of some iconv pipes? */
308    static int compatible_encodings (const char *input, const char *output)
309    {
310    #ifdef MULTIBYTE_GROFF
311            /* NULL output means that its encoding is passed through from the
312             * input, so it must be compatible.
313             */
314            if (!output)
315                    return 1;
316    #endif /* MULTIBYTE_GROFF */
317    
318            if (STREQ (input, output))
319                    return 1;
320    
321            /* If the input is ASCII, recoding should be easy. Try it. */
322            if (STREQ (input, "ANSI_X3.4-1968"))
323                    return 1;
324    
325            /* If the input is UTF-8, it's either a simple recoding of whatever
326             * we want or else it probably won't work at all no matter what we
327             * do. We might as well try it for now.
328             */
329            if (STREQ (input, "UTF-8"))
330                    return 1;
331    
332    #ifdef MULTIBYTE_GROFF
333            /* Special case for ja_JP.UTF-8, which takes UTF-8 input recoded
334             * from EUC-JP and produces UTF-8 output. This is rather filthy.
335             */
336            if (STREQ (input, "EUC-JP") && STREQ (output, "UTF-8"))
337                    return 1;
338    #endif /* MULTIBYTE_GROFF */
339    
340            return 0;
341    }
342    
343  /* Return the default groff device for the given character set. This may be  /* Return the default groff device for the given character set. This may be
344   * overridden by the user.   * overridden by the user. The page's source encoding is needed to ensure
345     * that the device is compatible: consider ru_RU.UTF-8, which needs ascii8
346     * and a trailing iconv pipe to recode to UTF-8.
347     *
348     * All this encoding compatibility stuff feels like a slightly nasty hack,
349     * but I haven't yet come up with a cleaner way to do it.
350   */   */
351  const char *get_default_device (const char *locale_charset)  const char *get_default_device (const char *locale_charset,
352                                    const char *source_encoding)
353  {  {
354          int i;          int i;
355    
356          if (!locale_charset)          if (!locale_charset || !source_encoding)
357                  return fallback_default_device;                  return fallback_default_device;
358    
359          for (i = 0; charset_table[i].locale_charset; ++i) {          for (i = 0; charset_table[i].locale_charset; ++i) {
360                  if (STREQ (charset_table[i].locale_charset, locale_charset))                  const struct charset_entry *entry = &charset_table[i];
361                          return charset_table[i].default_device;                  if (STREQ (entry->locale_charset, locale_charset)) {
362                            const char *roff_encoding =
363                                    get_roff_encoding (entry->default_device);
364                            if (compatible_encodings (source_encoding,
365                                                      roff_encoding))
366                                    return entry->default_device;
367                    }
368          }          }
369    
370          return fallback_default_device;          return fallback_default_device;
# Line 301  const char *get_roff_encoding (const cha Line 378  const char *get_roff_encoding (const cha
378  {  {
379          int i;          int i;
380          int found = 0;          int found = 0;
381          const char *roff_encoding = NULL, *less_charset = NULL;          const char *roff_encoding = NULL;
382    
383          for (i = 0; device_table[i].roff_device; ++i) {          for (i = 0; device_table[i].roff_device; ++i) {
384                  if (STREQ (device_table[i].roff_device, device)) {                  if (STREQ (device_table[i].roff_device, device)) {
385                          found = 1;                          found = 1;
386                          roff_encoding = device_table[i].roff_encoding;                          roff_encoding = device_table[i].roff_encoding;
                         less_charset = device_table[i].less_charset;  
387                          break;                          break;
388                  }                  }
389          }          }
390    
391          if (!found) {          if (!found)
                 less_charset = fallback_less_charset;  
392                  roff_encoding = fallback_roff_encoding;                  roff_encoding = fallback_roff_encoding;
         }  
393    
394  #ifdef MULTIBYTE_GROFF  #ifdef MULTIBYTE_GROFF
395          /* An ugly special case is needed here. The utf8 device normally          /* An ugly special case is needed here. The utf8 device normally
# Line 331  const char *get_roff_encoding (const cha Line 405  const char *get_roff_encoding (const cha
405          }          }
406  #endif /* MULTIBYTE_GROFF */  #endif /* MULTIBYTE_GROFF */
407    
         putenv (strappend (NULL, "LESSCHARSET=", less_charset, NULL));  
408          return roff_encoding;          return roff_encoding;
409  }  }
410    
411    /* Find the output encoding that this device will produce, or NULL if it
412     * will simply pass through the input encoding.
413     */
414    const char *get_output_encoding (const char *device)
415    {
416            int i;
417    
418            for (i = 0; device_table[i].roff_device; ++i)
419                    if (STREQ (device_table[i].roff_device, device))
420                            return device_table[i].output_encoding;
421    
422            return NULL;
423    }
424    
425    /* Return the value of LESSCHARSET appropriate for this locale. */
426    const char *get_less_charset (const char *locale_charset)
427    {
428            int i;
429    
430            for (i = 0; less_charset_table[i].locale_charset; ++i) {
431                    const struct less_charset_entry *entry =
432                            &less_charset_table[i];
433                    if (STREQ (entry->locale_charset, locale_charset))
434                            return entry->less_charset;
435            }
436    
437            return fallback_less_charset;
438    }

Legend:
Removed from v.1.5  
changed lines
  Added in v.1.6

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26