1177997Skib/* Copyright (C) 1991, 1996, 1997, 2002 Free Software Foundation, Inc.
2177997Skib   This file is part of the GNU C Library.
3177997Skib
4177997Skib   The GNU C Library is free software; you can redistribute it and/or
5177997Skib   modify it under the terms of the GNU Lesser General Public
6177997Skib   License as published by the Free Software Foundation; either
7177997Skib   version 2.1 of the License, or (at your option) any later version.
8177997Skib
9177997Skib   The GNU C Library is distributed in the hope that it will be useful,
10177997Skib   but WITHOUT ANY WARRANTY; without even the implied warranty of
11177997Skib   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12177997Skib   Lesser General Public License for more details.
13177997Skib
14177997Skib   You should have received a copy of the GNU Lesser General Public
15177997Skib   License along with the GNU C Library; if not, write to the Free
16177997Skib   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17177997Skib   02111-1307 USA.
18177997Skib*/
19177997Skib
20177997Skib
21177997Skib#include <stdio_private.h>
22177997Skib#include <errno.h>
23177997Skib#include <limits.h>
24177997Skib#include <printf.h>
25177997Skib#include <stddef.h>
26177997Skib#include <stdlib.h>
27177997Skib
28177997Skib
29177997Skib/* Array of functions indexed by format character.  */
30177997Skiblibc_freeres_ptr (printf_arginfo_function **__printf_arginfo_table)
31177997Skib  attribute_hidden;
32177997Skibprintf_function **__printf_function_table attribute_hidden;
33177997Skib
34227693Sedint __register_printf_function __P ((int, printf_function,
35177997Skib                                     printf_arginfo_function));
36227693Sed
37177997Skib/* Register FUNC to be called to format SPEC specifiers.  */
38246085Sjhbint
39246085Sjhb__register_printf_function (spec, converter, arginfo)
40246085Sjhb     int spec;
41246085Sjhb     printf_function converter;
42246085Sjhb     printf_arginfo_function arginfo;
43246085Sjhb{
44246085Sjhb  if (spec < 0 || spec > (int) UCHAR_MAX)
45246085Sjhb    {
46246085Sjhb      __set_errno (EINVAL);
47246085Sjhb      return -1;
48246085Sjhb    }
49246085Sjhb
50246085Sjhb  if (__printf_function_table == NULL)
51246085Sjhb    {
52246085Sjhb      __printf_arginfo_table = (printf_arginfo_function **)
53246085Sjhb	malloc ((UCHAR_MAX + 1) * sizeof (void *) * 2);
54246085Sjhb      if (__printf_arginfo_table == NULL)
55246085Sjhb	return -1;
56246085Sjhb      __printf_function_table = (printf_function **)
57283437Sdchagin	(__printf_arginfo_table + UCHAR_MAX + 1);
58283437Sdchagin    }
59283437Sdchagin
60283437Sdchagin  __printf_function_table[spec] = converter;
61283437Sdchagin  __printf_arginfo_table[spec] = arginfo;
62283437Sdchagin
63283437Sdchagin  return 0;
64283437Sdchagin}
65283437Sdchaginweak_alias (__register_printf_function, register_printf_function)
66283437Sdchagin