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