Wrap too-long log entry.
[glibc.git] / stdio-common / reg-modifier.c
blobdcfd3a812a467bc08ffbe68c4494b4a1e6096cb4
1 /* Copyright (C) 2009 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, see
16 <http://www.gnu.org/licenses/>. */
18 #include <errno.h>
19 #include <limits.h>
20 #include <printf.h>
21 #include <wchar.h>
22 #include <bits/libc-lock.h>
25 struct printf_modifier_record
27 struct printf_modifier_record *next;
28 int bit;
29 wchar_t str[0];
32 struct printf_modifier_record **__printf_modifier_table attribute_hidden;
34 __libc_lock_define_initialized (static, lock)
36 /* Bits to hand out. */
37 static int next_bit;
40 int
41 __register_printf_modifier (const wchar_t *str)
43 if (str[0] == L'\0')
45 einval:
46 __set_errno (EINVAL);
47 return -1;
50 const wchar_t *wc = str;
51 while (*wc != L'\0')
52 if (*wc < 0 || *wc > (wchar_t) UCHAR_MAX)
53 goto einval;
54 else
55 ++wc;
57 if (next_bit / 8 == sizeof (((struct printf_info *) NULL)->user))
59 __set_errno (ENOSPC);
60 return -1;
63 int result = -1;
64 __libc_lock_lock (lock);
66 if (__printf_modifier_table == NULL)
68 __printf_modifier_table = calloc (UCHAR_MAX,
69 sizeof (*__printf_modifier_table));
70 if (__printf_modifier_table == NULL)
71 goto out;
74 /* Create enough room for the string. But we don't need the first
75 character. */
76 struct printf_modifier_record *newp = malloc (sizeof (*newp)
77 + ((wc - str)
78 * sizeof (wchar_t)));
79 if (newp == NULL)
80 goto out;
82 newp->next = __printf_modifier_table[(unsigned char) *str];
83 newp->bit = 1 << next_bit++;
84 __wmemcpy (newp->str, str + 1, wc - str);
86 __printf_modifier_table[(unsigned char) *str] = newp;
88 result = newp->bit;
90 out:
91 __libc_lock_unlock (lock);
93 return result;
95 weak_alias (__register_printf_modifier, register_printf_modifier)
98 #include <stdio.h>
99 int
100 attribute_hidden
101 __handle_registered_modifier_mb (const unsigned char **format,
102 struct printf_info *info)
104 struct printf_modifier_record *runp = __printf_modifier_table[**format];
106 int best_bit = 0;
107 int best_len = 0;
108 const unsigned char *best_cp = NULL;
110 while (runp != NULL)
112 const unsigned char *cp = *format + 1;
113 wchar_t *fcp = runp->str;
115 while (*cp != '\0' && *fcp != L'\0')
116 if (*cp != *fcp)
117 break;
118 else
119 ++cp, ++fcp;
121 if (*fcp == L'\0' && cp - *format > best_len)
123 best_cp = cp;
124 best_len = cp - *format;
125 best_bit = runp->bit;
128 runp = runp->next;
131 if (best_bit != 0)
133 info->user |= best_bit;
134 *format = best_cp;
135 return 0;
138 return 1;
143 attribute_hidden
144 __handle_registered_modifier_wc (const unsigned int **format,
145 struct printf_info *info)
147 struct printf_modifier_record *runp = __printf_modifier_table[**format];
149 int best_bit = 0;
150 int best_len = 0;
151 const unsigned int *best_cp = NULL;
153 while (runp != NULL)
155 const unsigned int *cp = *format + 1;
156 wchar_t *fcp = runp->str;
158 while (*cp != '\0' && *fcp != L'\0')
159 if (*cp != *fcp)
160 break;
161 else
162 ++cp, ++fcp;
164 if (*fcp == L'\0' && cp - *format > best_len)
166 best_cp = cp;
167 best_len = cp - *format;
168 best_bit = runp->bit;
171 runp = runp->next;
174 if (best_bit != 0)
176 info->user |= best_bit;
177 *format = best_cp;
178 return 0;
181 return 1;
185 libc_freeres_fn (free_mem)
187 if (__printf_modifier_table != NULL)
189 for (int i = 0; i < UCHAR_MAX; ++i)
191 struct printf_modifier_record *runp = __printf_modifier_table[i];
192 while (runp != NULL)
194 struct printf_modifier_record *oldp = runp;
195 runp = runp->next;
196 free (oldp);
199 free (__printf_modifier_table);