1/*
2 * Array test program for CUPS.
3 *
4 * Copyright 2007-2014 by Apple Inc.
5 * Copyright 1997-2006 by Easy Software Products.
6 *
7 * These coded instructions, statements, and computer programs are the
8 * property of Apple Inc. and are protected by Federal copyright
9 * law.  Distribution and use rights are outlined in the file "LICENSE.txt"
10 * which should have been included with this file.  If this file is
11 * missing or damaged, see the license at "http://www.cups.org/".
12 *
13 * This file is subject to the Apple OS-Developed Software exception.
14 */
15
16/*
17 * Include necessary headers...
18 */
19
20#include "string-private.h"
21#include "debug-private.h"
22#include "array-private.h"
23#include "dir.h"
24
25
26/*
27 * Local functions...
28 */
29
30static double	get_seconds(void);
31static int	load_words(const char *filename, cups_array_t *array);
32
33
34/*
35 * 'main()' - Main entry.
36 */
37
38int					/* O - Exit status */
39main(void)
40{
41  int		i;			/* Looping var */
42  cups_array_t	*array,			/* Test array */
43		*dup_array;		/* Duplicate array */
44  int		status;			/* Exit status */
45  char		*text;			/* Text from array */
46  char		word[256];		/* Word from file */
47  double	start,			/* Start time */
48		end;			/* End time */
49  cups_dir_t	*dir;			/* Current directory */
50  cups_dentry_t	*dent;			/* Directory entry */
51  char		*saved[32];		/* Saved entries */
52  void		*data;			/* User data for arrays */
53
54
55 /*
56  * No errors so far...
57  */
58
59  status = 0;
60
61 /*
62  * cupsArrayNew()
63  */
64
65  fputs("cupsArrayNew: ", stdout);
66
67  data  = (void *)"testarray";
68  array = cupsArrayNew((cups_array_func_t)strcmp, data);
69
70  if (array)
71    puts("PASS");
72  else
73  {
74    puts("FAIL (returned NULL, expected pointer)");
75    status ++;
76  }
77
78 /*
79  * cupsArrayUserData()
80  */
81
82  fputs("cupsArrayUserData: ", stdout);
83  if (cupsArrayUserData(array) == data)
84    puts("PASS");
85  else
86  {
87    printf("FAIL (returned %p instead of %p!)\n", cupsArrayUserData(array),
88           data);
89    status ++;
90  }
91
92 /*
93  * cupsArrayAdd()
94  */
95
96  fputs("cupsArrayAdd: ", stdout);
97
98  if (!cupsArrayAdd(array, strdup("One Fish")))
99  {
100    puts("FAIL (\"One Fish\")");
101    status ++;
102  }
103  else
104  {
105    if (!cupsArrayAdd(array, strdup("Two Fish")))
106    {
107      puts("FAIL (\"Two Fish\")");
108      status ++;
109    }
110    else
111    {
112      if (!cupsArrayAdd(array, strdup("Red Fish")))
113      {
114	puts("FAIL (\"Red Fish\")");
115	status ++;
116      }
117      else
118      {
119        if (!cupsArrayAdd(array, strdup("Blue Fish")))
120	{
121	  puts("FAIL (\"Blue Fish\")");
122	  status ++;
123	}
124	else
125	  puts("PASS");
126      }
127    }
128  }
129
130 /*
131  * cupsArrayCount()
132  */
133
134  fputs("cupsArrayCount: ", stdout);
135  if (cupsArrayCount(array) == 4)
136    puts("PASS");
137  else
138  {
139    printf("FAIL (returned %d, expected 4)\n", cupsArrayCount(array));
140    status ++;
141  }
142
143 /*
144  * cupsArrayFirst()
145  */
146
147  fputs("cupsArrayFirst: ", stdout);
148  if ((text = (char *)cupsArrayFirst(array)) != NULL &&
149      !strcmp(text, "Blue Fish"))
150    puts("PASS");
151  else
152  {
153    printf("FAIL (returned \"%s\", expected \"Blue Fish\")\n", text);
154    status ++;
155  }
156
157 /*
158  * cupsArrayNext()
159  */
160
161  fputs("cupsArrayNext: ", stdout);
162  if ((text = (char *)cupsArrayNext(array)) != NULL &&
163      !strcmp(text, "One Fish"))
164    puts("PASS");
165  else
166  {
167    printf("FAIL (returned \"%s\", expected \"One Fish\")\n", text);
168    status ++;
169  }
170
171 /*
172  * cupsArrayLast()
173  */
174
175  fputs("cupsArrayLast: ", stdout);
176  if ((text = (char *)cupsArrayLast(array)) != NULL &&
177      !strcmp(text, "Two Fish"))
178    puts("PASS");
179  else
180  {
181    printf("FAIL (returned \"%s\", expected \"Two Fish\")\n", text);
182    status ++;
183  }
184
185 /*
186  * cupsArrayPrev()
187  */
188
189  fputs("cupsArrayPrev: ", stdout);
190  if ((text = (char *)cupsArrayPrev(array)) != NULL &&
191      !strcmp(text, "Red Fish"))
192    puts("PASS");
193  else
194  {
195    printf("FAIL (returned \"%s\", expected \"Red Fish\")\n", text);
196    status ++;
197  }
198
199 /*
200  * cupsArrayFind()
201  */
202
203  fputs("cupsArrayFind: ", stdout);
204  if ((text = (char *)cupsArrayFind(array, (void *)"One Fish")) != NULL &&
205      !strcmp(text, "One Fish"))
206    puts("PASS");
207  else
208  {
209    printf("FAIL (returned \"%s\", expected \"One Fish\")\n", text);
210    status ++;
211  }
212
213 /*
214  * cupsArrayCurrent()
215  */
216
217  fputs("cupsArrayCurrent: ", stdout);
218  if ((text = (char *)cupsArrayCurrent(array)) != NULL &&
219      !strcmp(text, "One Fish"))
220    puts("PASS");
221  else
222  {
223    printf("FAIL (returned \"%s\", expected \"One Fish\")\n", text);
224    status ++;
225  }
226
227 /*
228  * cupsArrayDup()
229  */
230
231  fputs("cupsArrayDup: ", stdout);
232  if ((dup_array = cupsArrayDup(array)) != NULL &&
233      cupsArrayCount(dup_array) == 4)
234    puts("PASS");
235  else
236  {
237    printf("FAIL (returned %p with %d elements, expected pointer with 4 elements)\n",
238           dup_array, cupsArrayCount(dup_array));
239    status ++;
240  }
241
242 /*
243  * cupsArrayRemove()
244  */
245
246  fputs("cupsArrayRemove: ", stdout);
247  if (cupsArrayRemove(array, (void *)"One Fish") &&
248      cupsArrayCount(array) == 3)
249    puts("PASS");
250  else
251  {
252    printf("FAIL (returned 0 with %d elements, expected 1 with 4 elements)\n",
253           cupsArrayCount(array));
254    status ++;
255  }
256
257 /*
258  * cupsArrayClear()
259  */
260
261  fputs("cupsArrayClear: ", stdout);
262  cupsArrayClear(array);
263  if (cupsArrayCount(array) == 0)
264    puts("PASS");
265  else
266  {
267    printf("FAIL (%d elements, expected 0 elements)\n",
268           cupsArrayCount(array));
269    status ++;
270  }
271
272 /*
273  * Now load this source file and grab all of the unique words...
274  */
275
276  fputs("Load unique words: ", stdout);
277  fflush(stdout);
278
279  start = get_seconds();
280
281  if ((dir = cupsDirOpen(".")) == NULL)
282  {
283    puts("FAIL (cupsDirOpen failed)");
284    status ++;
285  }
286  else
287  {
288    while ((dent = cupsDirRead(dir)) != NULL)
289    {
290      i = (int)strlen(dent->filename) - 2;
291
292      if (i > 0 && dent->filename[i] == '.' &&
293          (dent->filename[i + 1] == 'c' ||
294	   dent->filename[i + 1] == 'h'))
295	load_words(dent->filename, array);
296    }
297
298    cupsDirClose(dir);
299
300    end = get_seconds();
301
302    printf("%d words in %.3f seconds (%.0f words/sec), ", cupsArrayCount(array),
303           end - start, cupsArrayCount(array) / (end - start));
304    fflush(stdout);
305
306    for (text = (char *)cupsArrayFirst(array); text;)
307    {
308     /*
309      * Copy this word to the word buffer (safe because we strdup'd from
310      * the same buffer in the first place... :)
311      */
312
313      strlcpy(word, text, sizeof(word));
314
315     /*
316      * Grab the next word and compare...
317      */
318
319      if ((text = (char *)cupsArrayNext(array)) == NULL)
320	break;
321
322      if (strcmp(word, text) >= 0)
323	break;
324    }
325
326    if (text)
327    {
328      printf("FAIL (\"%s\" >= \"%s\"!)\n", word, text);
329      status ++;
330    }
331    else
332      puts("PASS");
333  }
334
335 /*
336  * Test deleting with iteration...
337  */
338
339  fputs("Delete While Iterating: ", stdout);
340
341  text = (char *)cupsArrayFirst(array);
342  cupsArrayRemove(array, text);
343  free(text);
344
345  text = (char *)cupsArrayNext(array);
346  if (!text)
347  {
348    puts("FAIL (cupsArrayNext returned NULL!)");
349    status ++;
350  }
351  else
352    puts("PASS");
353
354 /*
355  * Test save/restore...
356  */
357
358  fputs("cupsArraySave: ", stdout);
359
360  for (i = 0, text = (char *)cupsArrayFirst(array);
361       i < 32;
362       i ++, text = (char *)cupsArrayNext(array))
363  {
364    saved[i] = text;
365
366    if (!cupsArraySave(array))
367      break;
368  }
369
370  if (i < 32)
371    printf("FAIL (depth = %d)\n", i);
372  else
373    puts("PASS");
374
375  fputs("cupsArrayRestore: ", stdout);
376
377  while (i > 0)
378  {
379    i --;
380
381    text = cupsArrayRestore(array);
382    if (text != saved[i])
383      break;
384  }
385
386  if (i)
387    printf("FAIL (depth = %d)\n", i);
388  else
389    puts("PASS");
390
391 /*
392  * Delete the arrays...
393  */
394
395  cupsArrayDelete(array);
396  cupsArrayDelete(dup_array);
397
398 /*
399  * Test the array with string functions...
400  */
401
402  fputs("_cupsArrayNewStrings(\" \\t\\nfoo bar\\tboo\\nfar\", ' '): ", stdout);
403  array = _cupsArrayNewStrings(" \t\nfoo bar\tboo\nfar", ' ');
404  if (!array)
405  {
406    status = 1;
407    puts("FAIL (unable to create array)");
408  }
409  else if (cupsArrayCount(array) != 4)
410  {
411    status = 1;
412    printf("FAIL (got %d elements, expected 4)\n", cupsArrayCount(array));
413  }
414  else if (strcmp(text = (char *)cupsArrayFirst(array), "bar"))
415  {
416    status = 1;
417    printf("FAIL (first element \"%s\", expected \"bar\")\n", text);
418  }
419  else if (strcmp(text = (char *)cupsArrayNext(array), "boo"))
420  {
421    status = 1;
422    printf("FAIL (first element \"%s\", expected \"boo\")\n", text);
423  }
424  else if (strcmp(text = (char *)cupsArrayNext(array), "far"))
425  {
426    status = 1;
427    printf("FAIL (first element \"%s\", expected \"far\")\n", text);
428  }
429  else if (strcmp(text = (char *)cupsArrayNext(array), "foo"))
430  {
431    status = 1;
432    printf("FAIL (first element \"%s\", expected \"foo\")\n", text);
433  }
434  else
435    puts("PASS");
436
437  fputs("_cupsArrayAddStrings(array, \"foo2,bar2\", ','): ", stdout);
438  _cupsArrayAddStrings(array, "foo2,bar2", ',');
439
440  if (cupsArrayCount(array) != 6)
441  {
442    status = 1;
443    printf("FAIL (got %d elements, expected 6)\n", cupsArrayCount(array));
444  }
445  else if (strcmp(text = (char *)cupsArrayFirst(array), "bar"))
446  {
447    status = 1;
448    printf("FAIL (first element \"%s\", expected \"bar\")\n", text);
449  }
450  else if (strcmp(text = (char *)cupsArrayNext(array), "bar2"))
451  {
452    status = 1;
453    printf("FAIL (first element \"%s\", expected \"bar2\")\n", text);
454  }
455  else if (strcmp(text = (char *)cupsArrayNext(array), "boo"))
456  {
457    status = 1;
458    printf("FAIL (first element \"%s\", expected \"boo\")\n", text);
459  }
460  else if (strcmp(text = (char *)cupsArrayNext(array), "far"))
461  {
462    status = 1;
463    printf("FAIL (first element \"%s\", expected \"far\")\n", text);
464  }
465  else if (strcmp(text = (char *)cupsArrayNext(array), "foo"))
466  {
467    status = 1;
468    printf("FAIL (first element \"%s\", expected \"foo\")\n", text);
469  }
470  else if (strcmp(text = (char *)cupsArrayNext(array), "foo2"))
471  {
472    status = 1;
473    printf("FAIL (first element \"%s\", expected \"foo2\")\n", text);
474  }
475  else
476    puts("PASS");
477
478  cupsArrayDelete(array);
479
480 /*
481  * Summarize the results and return...
482  */
483
484  if (!status)
485    puts("\nALL TESTS PASSED!");
486  else
487    printf("\n%d TEST(S) FAILED!\n", status);
488
489  return (status);
490}
491
492
493/*
494 * 'get_seconds()' - Get the current time in seconds...
495 */
496
497#ifdef WIN32
498#  include <windows.h>
499
500
501static double
502get_seconds(void)
503{
504}
505#else
506#  include <sys/time.h>
507
508
509static double
510get_seconds(void)
511{
512  struct timeval	curtime;	/* Current time */
513
514
515  gettimeofday(&curtime, NULL);
516  return (curtime.tv_sec + 0.000001 * curtime.tv_usec);
517}
518#endif /* WIN32 */
519
520
521/*
522 * 'load_words()' - Load words from a file.
523 */
524
525static int				/* O - 1 on success, 0 on failure */
526load_words(const char   *filename,	/* I - File to load */
527           cups_array_t *array)		/* I - Array to add to */
528{
529  FILE		*fp;			/* Test file */
530  char		word[256];		/* Word from file */
531
532
533  if ((fp = fopen(filename, "r")) == NULL)
534  {
535    perror(filename);
536    return (0);
537  }
538
539  while (fscanf(fp, "%255s", word) == 1)
540  {
541    if (!cupsArrayFind(array, word))
542      cupsArrayAdd(array, strdup(word));
543  }
544
545  fclose(fp);
546
547  return (1);
548}
549