1/*
2 * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24#include "xlocale_private.h"
25
26#include <string.h>
27#include <rune.h>
28#include <stdlib.h>
29#include <wchar.h>
30#include "runedepreciated.h"
31
32__private_extern__ const char __rune_depreciated_msg[] = "\
33%s and other functions prototyped in rune.h are depreciated in favor of\n\
34the ISO C99 extended multibyte and wide character facilities and should not\n\
35be used in new applications.\n\
36";
37
38__private_extern__ rune_t
39__sgetrune(const char *string, size_t n, char const **result)
40{
41	wchar_t wc;
42	size_t converted = mbrtowc(&wc, string, n, NULL);
43	__darwin_rune_t invalid_rune = __current_locale()->__lc_ctype->_CurrentRuneLocale.__invalid_rune;
44
45	switch (converted) {
46	case (size_t)-2:	/* incomplete */
47		if (result)
48			*result = string;
49		return invalid_rune;
50	case (size_t)-1:	/* invalid */
51		if (result)
52			*result = string + 1;
53		return invalid_rune;
54	case (size_t)0:		/* null wide character */
55	{
56		int i;
57
58		for (i = 1; i < n; i++)
59			if (mbrtowc(&wc, string, n, NULL) == (size_t)0)
60				break;
61		if (result)
62			*result = string + i;
63		return (rune_t)0;
64	}
65	default:
66		if (result)
67			*result = string + converted;
68		return (rune_t)wc;
69	}
70	/* NOTREACHED */
71}
72
73__private_extern__ int
74__sputrune(rune_t rune, char *string, size_t n, char **result)
75{
76	char buf[MB_CUR_MAX];
77	size_t converted = wcrtomb(buf, rune, NULL);
78
79	if (converted == (size_t)-1) {
80		if (result)
81			*result = string;
82	} else if (n >= converted) {
83		if (string)
84			bcopy(buf, string, converted);
85		if (result)
86			*result = string + converted;
87	} else if (result)
88		*result = NULL;
89	return (converted == (size_t)-1 ? 0 : converted);
90}
91
92__private_extern__ rune_t
93sgetrune(const char *string, size_t n, char const **result)
94{
95	static int warn_depreciated = 1;
96
97	if (warn_depreciated) {
98		warn_depreciated = 0;
99		fprintf(stderr, __rune_depreciated_msg, "sgetrune");
100	}
101	return __sgetrune(string, n, result);
102}
103
104__private_extern__ int
105sputrune(rune_t rune, char *string, size_t n, char **result)
106{
107	static int warn_depreciated = 1;
108
109	if (warn_depreciated) {
110		warn_depreciated = 0;
111		fprintf(stderr, __rune_depreciated_msg, "sputrune");
112	}
113	return __sputrune(rune, string, n, result);
114}
115