1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /* ---- includes ----------------------------------------------------------- */
18 
19 #include "b_BasicEm/String.h"
20 /*
21 #include <stdlib.h>
22 */
23 
24 /* ---- related objects  --------------------------------------------------- */
25 
26 /* ---- typedefs ----------------------------------------------------------- */
27 
28 /* ---- constants ---------------------------------------------------------- */
29 
30 /* ------------------------------------------------------------------------- */
31 
32 /* ========================================================================= */
33 /*                                                                           */
34 /* ---- \ghd{ external functions } ----------------------------------------- */
35 /*                                                                           */
36 /* ========================================================================= */
37 
38 /* ------------------------------------------------------------------------- */
39 
bbs_strcpy(char * dstA,const char * srcA)40 char* bbs_strcpy( char* dstA, const char* srcA )
41 {
42 	const char* srcL = srcA;
43 	char* dstL = dstA;
44 	while( ( *dstL++ = *srcL++ ) != 0 );
45 	return dstA;
46 }
47 
48 /* ------------------------------------------------------------------------- */
49 
bbs_strncpy(char * dstA,const char * srcA,uint32 sizeA)50 char* bbs_strncpy( char* dstA, const char* srcA, uint32 sizeA )
51 {
52 	uint32 iL;
53 	for( iL = 0; iL < sizeA; iL++ )
54 	{
55 		if( ( dstA[ iL ] = srcA[ iL ] ) == 0 ) break;
56 	}
57 	if( iL == sizeA && sizeA > 0 ) dstA[ iL - 1 ] = 0;
58 	return dstA;
59 }
60 
61 /* ------------------------------------------------------------------------- */
62 
bbs_strcat(char * dstA,const char * srcA)63 char* bbs_strcat( char* dstA, const char* srcA )
64 {
65 	const char* srcL = srcA;
66 	char* dstL = dstA;
67 	while( *dstL != 0 ) dstL++;
68 	while( ( *dstL++ = *srcL++ ) != 0 );
69 	return dstA;
70 }
71 
72 /* ------------------------------------------------------------------------- */
73 
bbs_strncat(char * dstA,const char * srcA,uint32 sizeA)74 char* bbs_strncat( char* dstA, const char* srcA, uint32 sizeA )
75 {
76 	uint32 iL;
77 	for( iL = 0; iL < sizeA; iL++ )
78 	{
79 		if( dstA[ iL ] == 0 ) break;
80 	}
81 
82 	for( ; iL < sizeA; iL++ )
83 	{
84 		if( ( dstA[ iL ] = srcA[ iL ] ) == 0 ) break;
85 	}
86 
87 	if( iL == sizeA && sizeA > 0 ) dstA[ iL - 1 ] = 0;
88 
89 	return dstA;
90 }
91 
92 /* ------------------------------------------------------------------------- */
93 
bbs_strlen(const char * strA)94 uint32 bbs_strlen( const char* strA )
95 {
96 	uint32 iL = 0;
97 	while( strA[ iL++ ] != 0 );
98 	return iL - 1;
99 }
100 
101 /* ------------------------------------------------------------------------- */
102 
bbs_strequal(const char * str1A,const char * str2A)103 flag bbs_strequal( const char* str1A, const char* str2A )
104 {
105 	const char* str1L = str1A;
106 	const char* str2L = str2A;
107 
108 	if( str1L == NULL && str2L == NULL ) return TRUE;
109 	if( str1L == NULL || str2L == NULL ) return FALSE;
110 
111 	while( ( *str1L != 0 ) && ( *str2L != 0 ) )
112 	{
113 		if( *str1L != *str2L ) break;
114 		str1L++;
115 		str2L++;
116 	}
117 
118 	return *str1L == *str2L;
119 }
120 
121 /* ------------------------------------------------------------------------- */
122 
bbs_strmatch(const char * str1A,const char * str2A)123 flag bbs_strmatch( const char* str1A, const char* str2A )
124 {
125 	const char* str1L = str1A;
126 	const char* str2L = str2A;
127 
128 	if( str1L == NULL || str2L == NULL ) return TRUE;
129 
130 	while( ( *str1L != 0 ) && ( *str2L != 0 ) )
131 	{
132 		if( *str1L != *str2L ) break;
133 		str1L++;
134 		str2L++;
135 	}
136 
137 	if( *str1L == 0 || *str2L == 0 ) return TRUE;
138 
139 	return *str1L == *str2L;
140 }
141 
142 /* ------------------------------------------------------------------------- */
143 
bbs_snprintf(char * bufA,uint32 bufSizeA,const char * formatA,...)144 uint32 bbs_snprintf( char* bufA, uint32 bufSizeA, const char* formatA, ... )
145 {
146 	uint32 sizeL;
147 	va_list argsL;
148 	va_start( argsL, formatA );
149 	sizeL = bbs_vsnprintf( bufA, bufSizeA, formatA, argsL );
150 	va_end( argsL );
151 	return sizeL;
152 }
153 
154 /* ------------------------------------------------------------------------- */
155 
156 /* converts number to string without 0 termination - returns number of characters written */
bbs_cString(int32 valA,char * dstA,uint32 bufSizeA)157 uint32 bbs_cString( int32 valA, char* dstA, uint32 bufSizeA )
158 {
159 	uint32 valL = ( valA < 0 ) ? -valA : valA;
160 	uint32 iL = 0;
161 	uint32 digitsL = 0;
162 	if( valA < 0 )
163 	{
164 		if( iL < bufSizeA ) dstA[ iL++ ] = '-';
165 	}
166 
167 	/* count #digits */
168 	if( valL == 0 )
169 	{
170 		iL++;
171 	}
172 	else
173 	{
174 		while( valL > 0 )
175 		{
176 			iL++;
177 			valL /= 10;
178 		}
179 	}
180 
181 	digitsL = ( iL > bufSizeA ) ? bufSizeA : iL;
182 
183 	valL = ( valA < 0 ) ? -valA : valA;
184 
185 	if( valL == 0 )
186 	{
187 		if( iL < bufSizeA ) dstA[ --iL ] = '0';
188 	}
189 	else
190 	{
191 		while( valL > 0 )
192 		{
193 			if( iL < bufSizeA ) dstA[ --iL ] = '0' + ( valL % 10 );
194 			valL /= 10;
195 		}
196 	}
197 
198 	return digitsL;
199 }
200 
201 /* ------------------------------------------------------------------------- */
202 
bbs_vsnprintf(char * bufA,uint32 bufSizeA,const char * formatA,va_list argsA)203 uint32 bbs_vsnprintf( char* bufA, uint32 bufSizeA, const char* formatA, va_list argsA )
204 {
205 	const char* fpL = formatA;
206 	uint32 iL = 0;
207 
208 	while( *fpL != 0 )
209 	{
210 		if( *fpL == '%' )
211 		{
212 			if( *( fpL + 1 ) == 'i' || *( fpL + 1 ) == 'd' )
213 			{
214 				int valL = va_arg( argsA, int );
215 				if( iL < bufSizeA )
216 				{
217 					iL += bbs_cString( valL, bufA + iL, bufSizeA - iL );
218 				}
219 				fpL += 2;
220 			}
221 			else if( *( fpL + 1 ) == 's' )
222 			{
223 				const char* stringL = va_arg( argsA, char* );
224 				if( iL < bufSizeA )
225 				{
226 					bufA[ iL ] = 0;
227 					bbs_strncat( bufA + iL, stringL, bufSizeA - iL );
228 					iL += bbs_strlen( stringL );
229 				}
230 				fpL += 2;
231 			}
232 			else if( *( fpL + 1 ) == '%' )
233 			{
234 				if( iL < bufSizeA ) bufA[ iL++ ] = '%';
235 				fpL++;
236 			}
237 			else
238 			{
239 				if( iL < bufSizeA ) bufA[ iL++ ] = *fpL;
240 				fpL++;
241 			}
242 		}
243 		else
244 		{
245 			if( iL < bufSizeA ) bufA[ iL++ ] = *fpL;
246 			fpL++;
247 		}
248 	}
249 
250 	if( iL < bufSizeA )
251 	{
252 		bufA[ iL ] = 0;
253 	}
254 	else if( bufSizeA > 0 )
255 	{
256 		bufA[ bufSizeA - 1 ] = 0;
257 	}
258 
259 	return iL;
260 }
261 
262 /* ------------------------------------------------------------------------- */
263 
bbs_atoi(const char * strA)264 int32 bbs_atoi( const char* strA )
265 {
266 	int32 valL = 0;
267 	int16 signL = 1;
268 	uint16 iL = 0, lenL = bbs_strlen( strA );
269 
270 	while( iL < lenL && strA[ iL ] == ' ' ) iL++;
271 	if( strA[ iL ] == '-' )
272 	{
273 		signL = -1;
274 		iL++;
275 	}
276 	while( iL < lenL && strA[ iL ] == ' ' ) iL++;
277 	while( iL < lenL && strA[ iL ] >= '0' && strA[ iL ] <= '9' )
278 	{
279 		valL = valL * 10 + ( strA[ iL ] - '0' );
280 		iL++;
281 	}
282 	return valL * signL;
283 }
284 
285 /* ------------------------------------------------------------------------- */
286 
287