1/*
2 *
3 *   Copyright (c) International Business Machines  Corp., 2002
4 *
5 *   This program is free software;  you can redistribute it and/or modify
6 *   it under the terms of the GNU General Public License as published by
7 *   the Free Software Foundation; either version 2 of the License, or
8 *   (at your option) any later version.
9 *
10 *   This program is distributed in the hope that it will be useful,
11 *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
12 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13 *   the GNU General Public License for more details.
14 *
15 *   You should have received a copy of the GNU General Public License
16 *   along with this program;  if not, write to the Free Software
17 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20/* 01/02/2003	Port to LTP avenkat@us.ibm.com */
21/* 06/30/2001	Port to Linux	nsharoff@us.ibm.com */
22
23/*
24 * NAME
25 *	string01.c -  check string functions.
26 *
27 * CALLS
28 *	strchr, strrchr, strcat, strcmp, strcpy, strlen,
29 *	  strncat, strncmp, strncpy
30 *
31 * ALGORITHM
32 *	Test functionality of the string functions:
33 *		(strchr, strrchr, strcat, strcmp, strcpy, strlen,
34 *		 strncat, strncmp, strncpy )
35 *
36 */
37
38#include <stdio.h>
39#include <sys/types.h>
40#include <string.h>
41
42#include <errno.h>
43#include <stdlib.h>
44#include "test.h"
45
46#define FAILED 0
47#define PASSED 1
48
49char *TCID = "string01";
50
51int local_flag = PASSED;
52int block_number;
53FILE *temp;
54int TST_TOTAL = 1;
55/*****	**	** *****/
56
57#define LONGSTR	(96*1024-1)
58/* #define LONGSTR	(1024-1)		*/
59
60/*
61 *	Miscellaneous data strings for testing.
62 */
63
64char tiat[] = "This is a test of the string functions.  ";
65char yat[] = "This is yet another test.";
66char tiatyat[] =
67    "This is a test of the string functions.  This is yet another test.";
68
69char longstr[LONGSTR + 1];	/* a very long string */
70char dst0[LONGSTR + 1];		/* place holders for various tests */
71char dst1[LONGSTR + 1];
72char dst2[LONGSTR + 1];
73
74
75/*	Strlen	(strlen( s ) == e_res)		*/
76struct t_strlen {
77	char *s;
78	int e_res;
79} t_len[] = {
80	{
81	"", 0}, {
82	"12345", 5}, {
83	tiat, 41}, {
84	longstr, LONGSTR}, {
85	NULL, 0}
86};
87
88/*	Index	(index( s, c ) == e_res)		*/
89struct t_index {
90	char *s;
91	char c;
92	char *e_res;
93} t_index[] = {
94	{
95	"", 'z', NULL}, {
96	tiat, 'a', tiat + 8}, {
97	tiat, 's', tiat + 3}, {
98	tiat, 'o', tiat + 15}, {
99	tiat, 'z', NULL}, {
100	NULL, 0, NULL}
101};
102
103/*	Rindex	(rindex( s, c ) == e_res)		*/
104struct t_rindex {
105	char *s;
106	char c;
107	char *e_res;
108} t_rindex[] = {
109	{
110	"", 'z', NULL}, {
111	tiat, 'a', tiat + 8}, {
112	tiat, 's', tiat + 37}, {
113	tiat, 'o', tiat + 35}, {
114	tiat, 'z', NULL}, {
115	NULL, 0, NULL}
116};
117
118/*	Strcmp	(strcmp( s1, s2 ) == e_res)		*/
119struct t_strcmp {
120	char *s1;
121	char *s2;
122	int e_res;
123} t_cmp[] = {
124	{
125	"", "", 0}, {
126	"", tiat, -((int)'T')}, {
127	tiat, "", 'T'}, {
128	tiat, tiat, 0}, {
129	yat, tiat, 'y' - 'a'}, {
130	NULL, NULL, 0}
131};
132
133/*	Strcat	(strcmp( strcat(s1, s2),  s1s2 ) == e_res)		*/
134/*	ASSUMES strcmp is working -- it is tested prior to strcat	*/
135struct t_strcat {
136	char *s1;
137	char *s2;
138	char *s1s2;
139	int e_res;
140} t_cat[] = {
141	{
142	dst0, "", "", 0}, {
143	dst0, tiat, tiat, 0}, {
144	dst0, "", tiat, 0}, {
145	dst0, yat, tiatyat, 0}, {
146	dst1, longstr, longstr, 0}, {
147	NULL, NULL, NULL, 0}
148};
149
150/*	Strcpy	(strcmp( strcpy(s1, s2),  s1s2 ) == e_res)		*/
151/*	ASSUMES strcmp is working -- it is tested prior to strcpy	*/
152/*	No overlapping copies are tested				*/
153struct t_strcpy {
154	char *s1;
155	char *s2;
156	int e_res;
157} t_cpy[] = {
158	{
159	dst0, "", 0}, {
160	dst0, tiat, 0}, {
161	dst0, longstr, 0}, {
162	NULL, NULL, 0}
163};
164
165/*	Strncmp	(strncmp( s1, s2 ) == e_res)		*/
166struct t_strncmp {
167	char *s1;
168	char *s2;
169	int n;
170	int e_res;
171	int a_res;		/* Allowable results, some platforms only return 1 or -1 */
172} t_ncmp[] = {
173	{
174	"", "", 0, 0, 0}, {
175	"", "", 80, 0, 0}, {
176	tiat, "", 0, 0, 0}, {
177	"", tiat, 80, -((int)'T'), -1}, {
178	tiat, "", 80, 'T', 1}, {
179	tiat, tiat, 80, 0, 0}, {
180	yat, tiat, 80, 'y' - 'a', 1}, {
181	yat, tiat, 8, 0, 1}, {
182	yat, tiat, 9, 'y' - 'a', 1}, {
183	NULL, NULL, 0, 0, 0}
184
185};
186
187/*	Strncat	(strcmp( strncat(s1, s2, n),  s1ns2 ) == e_res)	*/
188/*	ASSUMES strcmp is working -- it is tested prior to strncat	*/
189/*	dest is guaranteed to be all '\0' s at start of test		*/
190struct t_strncat {
191	char *s1;
192	char *s2;
193	int n;
194	char *s1ns2;
195	int e_res;
196} t_ncat[] = {
197	/*      Regular strcat stuff -- i.e., n is large enough         */
198	{
199	dst0, "", LONGSTR, "", 0}, {
200	dst0, tiat, LONGSTR, tiat, 0}, {
201	dst0, "", LONGSTR, tiat, 0}, {
202	dst0, yat, LONGSTR, tiatyat, 0}, {
203	dst1, longstr, LONGSTR, longstr, 0},
204	    /*      Restricted strcat stuff                                 */
205	{
206	dst2, longstr, 0, "", 0}, {
207	dst2, longstr, 1, "t", 0}, {
208	dst2, longstr, LONGSTR - 1, longstr, 0}, {
209	NULL, NULL, 0, NULL, 0}
210
211};
212
213/*	Strncpy	(strcmp( strncpy(s1, s2),  s1n ) == e_res)		*/
214/*	ASSUMES strcmp is working -- it is tested prior to strncpy	*/
215/*	No overlapping copies are tested				*/
216struct t_strncpy {
217	char *s1;
218	char *s2;
219	int n;
220	char *s1n;
221	int e_res;
222} t_ncpy[] = {
223	/*      Regular strcpy stuff -- i.e., n is large enough         */
224	{
225	dst0, "", LONGSTR, "", 0}, {
226	dst0, tiat, LONGSTR, tiat, 0}, {
227	dst0, longstr, LONGSTR, longstr, 0},
228	    /*      Restricted strcpy stuff                                 */
229	{
230	dst1, tiat, 0, "", 0}, {
231	dst1, longstr, 5, "ttttt", 0}, {
232	NULL, NULL, 0, NULL, 0}
233};
234
235void setup();
236int blenter();
237int blexit();
238int anyfail();
239
240void setup(void)
241{
242	temp = stderr;
243}
244
245int blenter(void)
246{
247	local_flag = PASSED;
248	return 0;
249}
250
251int blexit(void)
252{
253	(local_flag == PASSED) ? tst_resm(TPASS,
254					  "Test passed") : tst_resm(TFAIL,
255								    "Test failed");
256	return 0;
257}
258
259int anyfail(void)
260{
261	tst_exit();
262}
263
264int main(int argc, char *argv[])
265{
266	register int n, i;
267	char *s, *pr;
268
269	tst_parse_opts(argc, argv, NULL, NULL);
270
271	/*
272	 * Init longstr
273	 */
274
275	s = longstr;
276	n = LONGSTR;
277	while (n--)
278		*s++ = 't';
279	*s = '\0';
280
281	setup();
282/*--------------------------------------------------------------*/
283
284	/*
285	 * Index
286	 */
287	//fprintf(temp, "\tStrchr\n" );
288	i = 0;
289	while (t_index[i].s) {
290		if ((pr =
291		     strchr(t_index[i].s, t_index[i].c)) != t_index[i].e_res) {
292			fprintf(temp, "(Strchr) test %d", i);
293			local_flag = FAILED;
294		}
295		i++;
296	}
297	/*
298	 * Strrchr
299	 */
300	//fprintf(temp, "\tStrrchr\n" );
301	i = 0;
302	while (t_rindex[i].s) {
303		if ((pr = strrchr(t_rindex[i].s, t_rindex[i].c))
304		    != t_rindex[i].e_res) {
305			fprintf(temp, "(Strrchr) test %d", i);
306			local_flag = FAILED;
307		}
308		i++;
309	}
310	/*
311	 * Strlen
312	 */
313	//fprintf(temp, "\tStrlen\n" );
314	i = 0;
315	while (t_len[i].s) {
316		if ((n = strlen(t_len[i].s)) != t_len[i].e_res) {
317			fprintf(temp, "(Strlen) test %d: expected %d, got %d",
318				i, t_len[i].e_res, n);
319			local_flag = FAILED;
320		}
321		i++;
322	}
323
324	/*
325	 * Strcmp
326	 */
327	//fprintf(temp, "\tStrcmp\n" );
328	i = 0;
329#define sign(x) ((x) < 0 ? -1 : ((x) > 0 ? 1 : 0))
330	while (t_cmp[i].s1) {
331		n = strcmp(t_cmp[i].s1, t_cmp[i].s2);
332		if (sign(n) != sign(t_cmp[i].e_res)) {
333			fprintf(temp, "(Strcmp) test %d: expected %d, got %d",
334				i, sign(t_cmp[i].e_res), sign(n));
335			local_flag = FAILED;
336		}
337		i++;
338	}
339
340	/*
341	 * Strcat
342	 */
343	//fprintf(temp, "\tStrcat\n" );
344	memset(dst0, 0, LONGSTR + 1);	/* clean slate */
345	memset(dst1, 0, LONGSTR + 1);	/* clean slate */
346	i = 0;
347	while (t_cat[i].s1) {
348		if ((n =
349		     strcmp(strcat(t_cat[i].s1, t_cat[i].s2), t_cat[i].s1s2))
350		    != t_cat[i].e_res) {
351			fprintf(temp, "(Strcat) test %d: expected %d, got %d",
352				i, t_cat[i].e_res, n);
353			local_flag = FAILED;
354		}
355		i++;
356	}
357
358	/*
359	 * Strcpy
360	 */
361	//fprintf(temp, "\tStrcpy\n" );
362	i = 0;
363	while (t_cpy[i].s1) {
364		if ((n = strcmp(strcpy(t_cpy[i].s1, t_cpy[i].s2), t_cpy[i].s2))
365		    != t_cpy[i].e_res) {
366			fprintf(temp, "(Strcpy) test %d: expected %d, got %d",
367				i, t_cpy[i].e_res, n);
368			local_flag = FAILED;
369		}
370		i++;
371	}
372
373	/*
374	 * Strncat
375	 */
376	//fprintf(temp, "\tStrncat\n" );
377	memset(dst0, 0, LONGSTR + 1);	/* clean slate */
378	memset(dst1, 0, LONGSTR + 1);	/* clean slate */
379	memset(dst2, 0, LONGSTR + 1);	/* clean slate */
380	i = 0;
381	while (t_ncat[i].s1) {
382		if ((n =
383		     strcmp(strncat(t_ncat[i].s1, t_ncat[i].s2, t_ncat[i].n),
384			    t_ncat[i].s1ns2)) != t_ncat[i].e_res) {
385			fprintf(temp, "(Strncat) test %d: expected %d, got %d",
386				i, t_ncat[i].e_res, n);
387			local_flag = FAILED;
388		}
389		i++;
390	}
391
392	/*
393	 * Strncmp
394	 */
395	//fprintf(temp, "\tStrncmp\n" );
396	i = 0;
397	while (t_ncmp[i].s1) {
398		if ((n = strncmp(t_ncmp[i].s1, t_ncmp[i].s2, t_ncmp[i].n))
399		    != t_ncmp[i].e_res) {
400			if ((t_ncmp[i].a_res < 0 && n > t_ncmp[i].a_res)
401			    || (t_ncmp[i].a_res > 0 && n < t_ncmp[i].a_res)) {
402				fprintf(temp,
403					"(Strncmp) test %d: expected %d, got %d",
404					i, t_ncmp[i].e_res, n);
405				local_flag = FAILED;
406			}
407		}
408		i++;
409	}
410
411	/*
412	 * Strncpy
413	 */
414	//fprintf(temp, "\tStrncpy\n" );
415	i = 0;
416	memset(dst0, 0, LONGSTR + 1);	/* clean slate */
417	memset(dst1, 0, LONGSTR + 1);	/* clean slate */
418	while (t_ncpy[i].s1) {
419		if ((n =
420		     strcmp(strncpy(t_ncpy[i].s1, t_ncpy[i].s2, t_ncpy[i].n),
421			    t_ncpy[i].s1n)) != t_ncpy[i].e_res) {
422			fprintf(temp, "(Strncpy) test %d: expected %d, got %d",
423				i, t_ncpy[i].e_res, n);
424			local_flag = FAILED;
425		}
426		i++;
427	}
428
429	blexit();
430	anyfail();
431	tst_exit();
432}
433