explodename.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. /* Copyright (C) 1995-2019 Free Software Foundation, Inc.
  2. Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU Lesser General Public License as published by
  5. the Free Software Foundation; either version 2.1 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Lesser General Public License for more details.
  11. You should have received a copy of the GNU Lesser General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  13. #ifdef HAVE_CONFIG_H
  14. # include <config.h>
  15. #endif
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include <sys/types.h>
  19. #include "loadinfo.h"
  20. /* On some strange systems still no definition of NULL is found. Sigh! */
  21. #ifndef NULL
  22. # if defined __STDC__ && __STDC__
  23. # define NULL ((void *) 0)
  24. # else
  25. # define NULL 0
  26. # endif
  27. #endif
  28. /* @@ end of prolog @@ */
  29. /* Split a locale name NAME into a leading language part and all the
  30. rest. Return a pointer to the first character after the language,
  31. i.e. to the first byte of the rest. */
  32. static char *_nl_find_language (const char *name);
  33. static char *
  34. _nl_find_language (const char *name)
  35. {
  36. while (name[0] != '\0' && name[0] != '_' && name[0] != '@' && name[0] != '.')
  37. ++name;
  38. return (char *) name;
  39. }
  40. int
  41. _nl_explode_name (char *name,
  42. const char **language, const char **modifier,
  43. const char **territory, const char **codeset,
  44. const char **normalized_codeset)
  45. {
  46. char *cp;
  47. int mask;
  48. *modifier = NULL;
  49. *territory = NULL;
  50. *codeset = NULL;
  51. *normalized_codeset = NULL;
  52. /* Now we determine the single parts of the locale name. First
  53. look for the language. Termination symbols are `_', '.', and `@'. */
  54. mask = 0;
  55. *language = cp = name;
  56. cp = _nl_find_language (*language);
  57. if (*language == cp)
  58. /* This does not make sense: language has to be specified. Use
  59. this entry as it is without exploding. Perhaps it is an alias. */
  60. cp = strchr (*language, '\0');
  61. else
  62. {
  63. if (cp[0] == '_')
  64. {
  65. /* Next is the territory. */
  66. cp[0] = '\0';
  67. *territory = ++cp;
  68. while (cp[0] != '\0' && cp[0] != '.' && cp[0] != '@')
  69. ++cp;
  70. mask |= XPG_TERRITORY;
  71. }
  72. if (cp[0] == '.')
  73. {
  74. /* Next is the codeset. */
  75. cp[0] = '\0';
  76. *codeset = ++cp;
  77. while (cp[0] != '\0' && cp[0] != '@')
  78. ++cp;
  79. mask |= XPG_CODESET;
  80. if (*codeset != cp && (*codeset)[0] != '\0')
  81. {
  82. *normalized_codeset = _nl_normalize_codeset (*codeset,
  83. cp - *codeset);
  84. if (*normalized_codeset == NULL)
  85. return -1;
  86. else if (strcmp (*codeset, *normalized_codeset) == 0)
  87. free ((char *) *normalized_codeset);
  88. else
  89. mask |= XPG_NORM_CODESET;
  90. }
  91. }
  92. }
  93. if (cp[0] == '@')
  94. {
  95. /* Next is the modifier. */
  96. cp[0] = '\0';
  97. *modifier = ++cp;
  98. if (cp[0] != '\0')
  99. mask |= XPG_MODIFIER;
  100. }
  101. if (*territory != NULL && (*territory)[0] == '\0')
  102. mask &= ~XPG_TERRITORY;
  103. if (*codeset != NULL && (*codeset)[0] == '\0')
  104. mask &= ~XPG_CODESET;
  105. return mask;
  106. }