1 #include "../../include/sane/config.h"
2 
3 #include <stdlib.h>
4 #include <sys/types.h>
5 #include <sys/stat.h>
6 #include <fcntl.h>
7 #include <errno.h>
8 #include <string.h>
9 #include <assert.h>
10 
11 /* sane includes for the sanei functions called */
12 #include "../include/sane/sane.h"
13 #include "../include/sane/saneopts.h"
14 #include "../include/sane/sanei.h"
15 #include "../include/sane/sanei_config.h"
16 
17 #define XSTR(s) STR(s)
18 #define STR(s) #s
19 #define CONFIG_PATH XSTR(TESTSUITE_SANEI_SRCDIR)
20 
21 /*
22  * variables and functions used by the tests below
23  */
24 
25 
26 /* range for constraint */
27 static const SANE_Range model_range = {
28   1000,				/* minimum */
29   2000,				/* maximum */
30   2				/* quantization */
31 };
32 
33 /* range for memory buffer size constraint */
34 static const SANE_Range buffer_range = {
35   1024,				/* minimum bytes */
36   2048 * 1024,			/* maximum bytes */
37   1024				/* quantization */
38 };
39 
40 /* range for int value in [0-15] */
41 static const SANE_Range value16_range = {
42   0,				/* minimum */
43   15,				/* maximum */
44   1				/* quantization */
45 };
46 
47 /* range for fixed height value */
48 static const SANE_Range height_range = {
49   SANE_FIX (0),			/* minimum */
50   SANE_FIX (29.7),		/* maximum */
51   0				/* no quantization : hard to do for float values ... */
52 };
53 
54 /* list of astra models */
55 static const SANE_String_Const astra_models[] =
56   { "610", "1220", "1600", "2000", NULL };
57 
58 /* string list */
59 static const SANE_String_Const string_list[] =
60   { "string1", "string2", "string3", "string4", NULL };
61 
62 /* last device name used for attach callback */
63 static char *lastdevname = NULL;
64 
65 static SANE_Status
check_config_attach(SANEI_Config * config, const char *devname, void __sane_unused__ *data)66 check_config_attach (SANEI_Config * config, const char *devname,
67                      void __sane_unused__ *data)
68 {
69   /* silence compiler warning for now */
70   if (config == NULL)
71     {
72       return SANE_STATUS_INVAL;
73     }
74 
75   fprintf (stdout, "attaching with devname '%s'\n", devname);
76   if (lastdevname != NULL)
77     {
78       free (lastdevname);
79     }
80   lastdevname = strdup (devname);
81   return SANE_STATUS_GOOD;
82 }
83 
84 /******************************/
85 /* start of tests definitions */
86 /******************************/
87 
88 /*
89  * non-existent config file
90  */
91 static void
inexistent_config(void)92 inexistent_config (void)
93 {
94   SANE_Status status;
95   SANEI_Config config;
96 
97   config.count = 0;
98   config.descriptors = NULL;
99   config.values = NULL;
100   status = sanei_configure_attach (CONFIG_PATH
101                                    "/data/inexistent.conf", &config,
102                                    NULL, NULL);
103 
104   /* check results */
105   assert (status != SANE_STATUS_GOOD);
106 }
107 
108 
109 /*
110  * no config struct
111  */
112 static void
null_config(void)113 null_config (void)
114 {
115   SANE_Status status;
116 
117   status =
118     sanei_configure_attach (CONFIG_PATH "/data/umax_pp.conf", NULL,
119                             check_config_attach, NULL);
120 
121   /* check results */
122   assert (status == SANE_STATUS_GOOD);
123 }
124 
125 
126 /*
127  * no attach function
128  */
129 static void
null_attach(void)130 null_attach (void)
131 {
132   SANE_Status status;
133 
134   status = sanei_configure_attach (CONFIG_PATH
135                                    "/data/umax_pp.conf", NULL, NULL, NULL);
136 
137   /* check results */
138   assert (status == SANE_STATUS_GOOD);
139 }
140 
141 
142 /*
143  * empty config : backend has no configuration option
144  */
145 static void
empty_config(void)146 empty_config (void)
147 {
148   SANE_Status status;
149   SANEI_Config config;
150 
151   config.count = 0;
152   config.descriptors = NULL;
153   config.values = NULL;
154   status =
155     sanei_configure_attach (CONFIG_PATH "/data/empty.conf",
156                             &config, check_config_attach, NULL);
157 
158   /* check results */
159   assert (status == SANE_STATUS_GOOD);
160 }
161 
162 
163 /*
164  * string option
165  */
166 static void
string_option(void)167 string_option (void)
168 {
169   SANE_Status status;
170   SANEI_Config config;
171   SANE_Char modelname[128];
172   SANE_Char vendor[128];
173   SANE_Option_Descriptor *options[2];
174   void *values[2];
175   int i;
176 
177   i = 0;
178   options[i] =
179     (SANE_Option_Descriptor *) malloc (sizeof (SANE_Option_Descriptor));
180   options[i]->name = "modelname";
181   options[i]->title = "model name";
182   options[i]->desc = "user provided scanner's model name";
183   options[i]->type = SANE_TYPE_STRING;
184   options[i]->unit = SANE_UNIT_NONE;
185   options[i]->size = 128;
186   options[i]->cap = SANE_CAP_SOFT_SELECT;
187   options[i]->constraint_type = SANE_CONSTRAINT_NONE;
188   values[i] = modelname;
189   i++;
190 
191   options[i] =
192     (SANE_Option_Descriptor *) malloc (sizeof (SANE_Option_Descriptor));
193   options[i]->name = "vendor";
194   options[i]->title = "vendor name";
195   options[i]->desc = "user provided scanner's vendor name";
196   options[i]->type = SANE_TYPE_STRING;
197   options[i]->unit = SANE_UNIT_NONE;
198   options[i]->size = 128;
199   options[i]->cap = SANE_CAP_SOFT_SELECT;
200   options[i]->constraint_type = SANE_CONSTRAINT_NONE;
201   values[i] = vendor;
202   i++;
203 
204   config.count = i;
205   config.descriptors = options;
206   config.values = values;
207 
208   /* configure and attach */
209   status =
210     sanei_configure_attach (CONFIG_PATH "/data/string.conf",
211                             &config, check_config_attach, NULL);
212 
213   /* check results */
214   assert (status == SANE_STATUS_GOOD);
215   assert (strcmp (modelname, "my model") == 0);
216   assert (strcmp (vendor, "my vendor") == 0);
217 }
218 
219 
220 /*
221  * int option
222  */
223 static void
int_option(void)224 int_option (void)
225 {
226   SANE_Status status;
227   SANEI_Config config;
228   SANE_Word modelnumber;
229   SANE_Option_Descriptor *options[1];
230   void *values[1];
231   int i;
232 
233   i = 0;
234   options[i] =
235     (SANE_Option_Descriptor *) malloc (sizeof (SANE_Option_Descriptor));
236   options[i]->name = "modelnumber";
237   options[i]->title = "model number";
238   options[i]->desc = "user provided scanner's model number";
239   options[i]->type = SANE_TYPE_INT;
240   options[i]->unit = SANE_UNIT_NONE;
241   options[i]->size = sizeof (SANE_Word);
242   options[i]->cap = SANE_CAP_SOFT_SELECT;
243   options[i]->constraint_type = SANE_CONSTRAINT_RANGE;
244   options[i]->constraint.range = &model_range;
245   values[i] = &modelnumber;
246   i++;
247 
248   config.descriptors = options;
249   config.values = values;
250   config.count = i;
251 
252   /* configure and attach */
253   status =
254     sanei_configure_attach (CONFIG_PATH "/data/int.conf", &config,
255                             check_config_attach, NULL);
256 
257   /* check results */
258   assert (status == SANE_STATUS_GOOD);
259   assert (modelnumber == 1234);
260 }
261 
262 
263 /*
264  * int option out of range
265  */
266 static void
wrong_range_int_option(void)267 wrong_range_int_option (void)
268 {
269   SANE_Status status;
270   SANEI_Config config;
271   SANE_Word modelnumber = -1;
272   SANE_Option_Descriptor *options[1];
273   void *values[1];
274   int i;
275 
276   i = 0;
277   options[i] =
278     (SANE_Option_Descriptor *) malloc (sizeof (SANE_Option_Descriptor));
279   options[i]->name = "modelnumber";
280   options[i]->title = "model number";
281   options[i]->desc = "user provided scanner's model number";
282   options[i]->type = SANE_TYPE_INT;
283   options[i]->unit = SANE_UNIT_NONE;
284   options[i]->size = sizeof (SANE_Word);
285   options[i]->cap = SANE_CAP_SOFT_SELECT;
286   options[i]->constraint_type = SANE_CONSTRAINT_RANGE;
287   options[i]->constraint.range = &model_range;
288   values[i] = &modelnumber;
289   i++;
290 
291   config.descriptors = options;
292   config.values = values;
293   config.count = i;
294 
295   /* configure and attach */
296   status =
297     sanei_configure_attach (CONFIG_PATH "/data/wrong-range.conf",
298                             &config, check_config_attach, NULL);
299 
300   /* check results */
301   assert (status == SANE_STATUS_INVAL);
302   assert (modelnumber == -1);
303 }
304 
305 
306 /*
307  * word array
308  */
309 static void
word_array_option(void)310 word_array_option (void)
311 {
312   SANE_Status status;
313   SANEI_Config config;
314   SANE_Word numbers[7];
315   SANE_Option_Descriptor *options[1];
316   void *values[1];
317   int i;
318 
319   i = 0;
320   options[i] =
321     (SANE_Option_Descriptor *) malloc (sizeof (SANE_Option_Descriptor));
322   options[i]->name = "numbers";
323   options[i]->title = "some numbers";
324   options[i]->desc = "an array of numbers";
325   options[i]->type = SANE_TYPE_INT;
326   options[i]->unit = SANE_UNIT_NONE;
327   options[i]->size = sizeof (SANE_Word) * 7;
328   options[i]->cap = SANE_CAP_SOFT_SELECT;
329   options[i]->constraint_type = SANE_CONSTRAINT_RANGE;
330   options[i]->constraint.range = &model_range;
331   values[i] = numbers;
332   i++;
333 
334   config.descriptors = options;
335   config.values = values;
336   config.count = i;
337 
338   /* configure and attach */
339   status =
340     sanei_configure_attach (CONFIG_PATH "/data/word-array.conf",
341                             &config, check_config_attach, NULL);
342 
343   /* check results */
344   assert (status == SANE_STATUS_GOOD);
345   for (i = 0; i < 7; i++)
346     {
347       assert (numbers[i] == 1000 + 100 * i);
348     }
349 }
350 
351 
352 /*
353  * string option with string list constraint
354  */
355 static void
string_list_option(void)356 string_list_option (void)
357 {
358   SANE_Status status;
359   SANEI_Config config;
360   SANE_Char choice[128];
361   SANE_Option_Descriptor *options[1];
362   void *values[1];
363   int i;
364 
365   i = 0;
366   options[i] =
367     (SANE_Option_Descriptor *) malloc (sizeof (SANE_Option_Descriptor));
368   options[i]->name = "string-choice";
369   options[i]->title = "string choice";
370   options[i]->desc = "one string among a fixed list";
371   options[i]->type = SANE_TYPE_STRING;
372   options[i]->unit = SANE_UNIT_NONE;
373   options[i]->size = 128;
374   options[i]->cap = SANE_CAP_SOFT_SELECT;
375   options[i]->constraint_type = SANE_CONSTRAINT_STRING_LIST;
376   options[i]->constraint.string_list = string_list;
377   values[i] = choice;
378   i++;
379 
380   config.descriptors = options;
381   config.values = values;
382   config.count = i;
383 
384   /* configure and attach */
385   status =
386     sanei_configure_attach (CONFIG_PATH "/data/string-list.conf",
387                             &config, check_config_attach, NULL);
388 
389   /* check results */
390   assert (status == SANE_STATUS_GOOD);
391   assert (strcmp (choice, "string3") == 0);
392 }
393 
394 
395 /*
396  * string option with string list constraint
397  */
398 static void
wrong_string_list_option(void)399 wrong_string_list_option (void)
400 {
401   SANE_Status status;
402   SANEI_Config config;
403   SANE_Char choice[128];
404   SANE_Option_Descriptor *options[1];
405   void *values[1];
406   int i;
407 
408   i = 0;
409   options[i] =
410     (SANE_Option_Descriptor *) malloc (sizeof (SANE_Option_Descriptor));
411   options[i]->name = "string-choice";
412   options[i]->title = "string choice";
413   options[i]->desc = "one string among a fixed list";
414   options[i]->type = SANE_TYPE_STRING;
415   options[i]->unit = SANE_UNIT_NONE;
416   options[i]->size = 128;
417   options[i]->cap = SANE_CAP_SOFT_SELECT;
418   options[i]->constraint_type = SANE_CONSTRAINT_STRING_LIST;
419   options[i]->constraint.string_list = string_list;
420   values[i] = choice;
421   i++;
422 
423   config.descriptors = options;
424   config.values = values;
425   config.count = i;
426 
427   choice[0] = 0;
428 
429   /* configure and attach */
430   status =
431     sanei_configure_attach (CONFIG_PATH
432                             "/data/wrong-string-list.conf", &config,
433 			    check_config_attach, NULL);
434 
435   /* check results */
436   assert (status == SANE_STATUS_INVAL);
437   assert (strcmp (choice, "") == 0);
438 }
439 
440 
441 /*
442  * real umax_pp confiugration file parsing
443  */
444 static void
umax_pp(void)445 umax_pp (void)
446 {
447   SANE_Status status;
448   SANEI_Config config;
449   SANE_Option_Descriptor *options[9];
450   void *values[9];
451   int i = 0;
452   /* placeholders for options */
453   SANE_Word buffersize = -1;
454   SANE_Word redgain = -1;
455   SANE_Word greengain = -1;
456   SANE_Word bluegain = -1;
457   SANE_Word redoffset = -1;
458   SANE_Word greenoffset = -1;
459   SANE_Word blueoffset = -1;
460   SANE_Char model[128];
461 
462   i = 0;
463   options[i] =
464     (SANE_Option_Descriptor *) malloc (sizeof (SANE_Option_Descriptor));
465   options[i]->name = "buffer";
466   options[i]->type = SANE_TYPE_INT;
467   options[i]->unit = SANE_UNIT_NONE;
468   options[i]->size = sizeof (SANE_Word);
469   options[i]->cap = SANE_CAP_SOFT_SELECT;
470   options[i]->constraint_type = SANE_CONSTRAINT_RANGE;
471   options[i]->constraint.range = &buffer_range;
472   values[i] = &buffersize;
473   i++;
474 
475   options[i] =
476     (SANE_Option_Descriptor *) malloc (sizeof (SANE_Option_Descriptor));
477   options[i]->name = "red-gain";
478   options[i]->type = SANE_TYPE_INT;
479   options[i]->unit = SANE_UNIT_NONE;
480   options[i]->size = sizeof (SANE_Word);
481   options[i]->cap = SANE_CAP_SOFT_SELECT;
482   options[i]->constraint_type = SANE_CONSTRAINT_RANGE;
483   options[i]->constraint.range = &value16_range;
484   values[i] = &redgain;
485   i++;
486 
487   options[i] =
488     (SANE_Option_Descriptor *) malloc (sizeof (SANE_Option_Descriptor));
489   options[i]->name = "green-gain";
490   options[i]->type = SANE_TYPE_INT;
491   options[i]->unit = SANE_UNIT_NONE;
492   options[i]->size = sizeof (SANE_Word);
493   options[i]->cap = SANE_CAP_SOFT_SELECT;
494   options[i]->constraint_type = SANE_CONSTRAINT_RANGE;
495   options[i]->constraint.range = &value16_range;
496   values[i] = &greengain;
497   i++;
498 
499   options[i] =
500     (SANE_Option_Descriptor *) malloc (sizeof (SANE_Option_Descriptor));
501   options[i]->name = "blue-gain";
502   options[i]->type = SANE_TYPE_INT;
503   options[i]->unit = SANE_UNIT_NONE;
504   options[i]->size = sizeof (SANE_Word);
505   options[i]->cap = SANE_CAP_SOFT_SELECT;
506   options[i]->constraint_type = SANE_CONSTRAINT_RANGE;
507   options[i]->constraint.range = &value16_range;
508   values[i] = &bluegain;
509   i++;
510 
511   options[i] =
512     (SANE_Option_Descriptor *) malloc (sizeof (SANE_Option_Descriptor));
513   options[i]->name = "red-offset";
514   options[i]->type = SANE_TYPE_INT;
515   options[i]->unit = SANE_UNIT_NONE;
516   options[i]->size = sizeof (SANE_Word);
517   options[i]->cap = SANE_CAP_SOFT_SELECT;
518   options[i]->constraint_type = SANE_CONSTRAINT_RANGE;
519   options[i]->constraint.range = &value16_range;
520   values[i] = &redoffset;
521   i++;
522 
523   options[i] =
524     (SANE_Option_Descriptor *) malloc (sizeof (SANE_Option_Descriptor));
525   options[i]->name = "green-offset";
526   options[i]->type = SANE_TYPE_INT;
527   options[i]->unit = SANE_UNIT_NONE;
528   options[i]->size = sizeof (SANE_Word);
529   options[i]->cap = SANE_CAP_SOFT_SELECT;
530   options[i]->constraint_type = SANE_CONSTRAINT_RANGE;
531   options[i]->constraint.range = &value16_range;
532   values[i] = &greenoffset;
533   i++;
534 
535   options[i] =
536     (SANE_Option_Descriptor *) malloc (sizeof (SANE_Option_Descriptor));
537   options[i]->name = "blue-offset";
538   options[i]->type = SANE_TYPE_INT;
539   options[i]->unit = SANE_UNIT_NONE;
540   options[i]->size = sizeof (SANE_Word);
541   options[i]->cap = SANE_CAP_SOFT_SELECT;
542   options[i]->constraint_type = SANE_CONSTRAINT_RANGE;
543   options[i]->constraint.range = &value16_range;
544   values[i] = &blueoffset;
545   i++;
546 
547   options[i] =
548     (SANE_Option_Descriptor *) malloc (sizeof (SANE_Option_Descriptor));
549   options[i]->name = "astra";
550   options[i]->type = SANE_TYPE_STRING;
551   options[i]->unit = SANE_UNIT_NONE;
552   options[i]->size = 128;
553   options[i]->cap = SANE_CAP_SOFT_SELECT;
554   options[i]->constraint_type = SANE_CONSTRAINT_STRING_LIST;
555   options[i]->constraint.string_list = astra_models;
556   values[i] = &model;
557   i++;
558 
559   config.descriptors = options;
560   config.values = values;
561   config.count = i;
562 
563   model[0] = 0;
564 
565   /* configure and attach */
566   status =
567     sanei_configure_attach (CONFIG_PATH "/data/umax_pp.conf",
568                             &config, check_config_attach, NULL);
569 
570   /* check results */
571   assert (status == SANE_STATUS_GOOD);
572   assert (buffersize == 1048576);
573   assert (redgain == 1);
574   assert (greengain == 2);
575   assert (bluegain == 3);
576   assert (redoffset == 4);
577   assert (greenoffset == 5);
578   assert (blueoffset == 6);
579   assert (strcmp (model, "1600") == 0);
580   assert (strcmp (lastdevname, "port safe-auto") == 0);
581 
582   /* free memory */
583   while (i > 0)
584     {
585       i--;
586       free (options[i]);
587     }
588 }
589 
590 
591 /*
592  * boolean option
593  */
594 static void
wrong_bool_option(void)595 wrong_bool_option (void)
596 {
597   SANE_Status status;
598   SANEI_Config config;
599   SANE_Option_Descriptor *options[2];
600   void *values[2];
601   SANE_Bool booltrue, boolfalse;
602   int i;
603 
604   i = 0;
605   options[i] =
606     (SANE_Option_Descriptor *) malloc (sizeof (SANE_Option_Descriptor));
607   options[i]->name = "booltrue";
608   options[i]->title = "boolean true";
609   options[i]->type = SANE_TYPE_BOOL;
610   options[i]->unit = SANE_UNIT_NONE;
611   options[i]->size = sizeof (SANE_Bool);
612   options[i]->cap = SANE_CAP_SOFT_SELECT;
613   options[i]->constraint_type = SANE_CONSTRAINT_NONE;
614   values[i] = &booltrue;
615   i++;
616 
617   options[i] =
618     (SANE_Option_Descriptor *) malloc (sizeof (SANE_Option_Descriptor));
619   options[i]->name = "boolfalse";
620   options[i]->title = "boolean false";
621   options[i]->type = SANE_TYPE_BOOL;
622   options[i]->unit = SANE_UNIT_NONE;
623   options[i]->size = sizeof (SANE_Bool);
624   options[i]->cap = SANE_CAP_SOFT_SELECT;
625   options[i]->constraint_type = SANE_CONSTRAINT_NONE;
626   values[i] = &boolfalse;
627   i++;
628 
629   config.descriptors = options;
630   config.values = values;
631   config.count = i;
632 
633   /* configure and attach */
634   status =
635     sanei_configure_attach (CONFIG_PATH "/data/wrong-boolean.conf",
636                             &config, check_config_attach, NULL);
637 
638   /* check results */
639   assert (status == SANE_STATUS_INVAL);
640   assert (booltrue == SANE_TRUE);
641 }
642 
643 
644 /*
645  * boolean option
646  */
647 static void
bool_option(void)648 bool_option (void)
649 {
650   SANE_Status status;
651   SANEI_Config config;
652   SANE_Option_Descriptor *options[3];
653   void *values[3];
654   SANE_Bool booltrue, boolfalse, boolarray[3];
655   int i;
656 
657   i = 0;
658   options[i] =
659     (SANE_Option_Descriptor *) malloc (sizeof (SANE_Option_Descriptor));
660   options[i]->name = "booltrue";
661   options[i]->title = "boolean true";
662   options[i]->type = SANE_TYPE_BOOL;
663   options[i]->unit = SANE_UNIT_NONE;
664   options[i]->size = sizeof (SANE_Bool);
665   options[i]->cap = SANE_CAP_SOFT_SELECT;
666   options[i]->constraint_type = SANE_CONSTRAINT_NONE;
667   values[i] = &booltrue;
668   i++;
669 
670   options[i] =
671     (SANE_Option_Descriptor *) malloc (sizeof (SANE_Option_Descriptor));
672   options[i]->name = "boolfalse";
673   options[i]->title = "boolean false";
674   options[i]->type = SANE_TYPE_BOOL;
675   options[i]->unit = SANE_UNIT_NONE;
676   options[i]->size = sizeof (SANE_Bool);
677   options[i]->cap = SANE_CAP_SOFT_SELECT;
678   options[i]->constraint_type = SANE_CONSTRAINT_NONE;
679   values[i] = &boolfalse;
680   i++;
681 
682   options[i] =
683     (SANE_Option_Descriptor *) malloc (sizeof (SANE_Option_Descriptor));
684   options[i]->name = "boolarray";
685   options[i]->title = "boolean array";
686   options[i]->type = SANE_TYPE_BOOL;
687   options[i]->unit = SANE_UNIT_NONE;
688   options[i]->size = sizeof (boolarray);
689   options[i]->cap = SANE_CAP_SOFT_SELECT;
690   options[i]->constraint_type = SANE_CONSTRAINT_NONE;
691   values[i] = boolarray;
692   i++;
693 
694   config.descriptors = options;
695   config.values = values;
696   config.count = i;
697 
698   /* configure and attach */
699   status =
700     sanei_configure_attach (CONFIG_PATH "/data/boolean.conf",
701                             &config, check_config_attach, NULL);
702 
703   /* check results */
704   assert (status == SANE_STATUS_GOOD);
705   assert (booltrue == SANE_TRUE);
706   assert (boolfalse == SANE_FALSE);
707   for (i = 0; i < 3; i++)
708     {
709       assert (boolarray[i] == (SANE_Bool) i % 2);
710     }
711 }
712 
713 
714 /*
715  * fixed option
716  */
717 static void
fixed_option(void)718 fixed_option (void)
719 {
720   SANE_Status status;
721   SANEI_Config config;
722   SANE_Word width, height, fixedarray[7];
723   SANE_Option_Descriptor *options[3];
724   void *values[3];
725   int i;
726 
727   i = 0;
728   options[i] =
729     (SANE_Option_Descriptor *) malloc (sizeof (SANE_Option_Descriptor));
730   options[i]->name = "width";
731   options[i]->title = "width";
732   options[i]->type = SANE_TYPE_FIXED;
733   options[i]->unit = SANE_UNIT_NONE;
734   options[i]->size = sizeof (SANE_Word);
735   options[i]->cap = SANE_CAP_SOFT_SELECT;
736   options[i]->constraint_type = SANE_CONSTRAINT_NONE;
737   values[i] = &width;
738   i++;
739 
740   options[i] =
741     (SANE_Option_Descriptor *) malloc (sizeof (SANE_Option_Descriptor));
742   options[i]->name = "height";
743   options[i]->title = "height";
744   options[i]->type = SANE_TYPE_FIXED;
745   options[i]->unit = SANE_UNIT_NONE;
746   options[i]->size = sizeof (SANE_Word);
747   options[i]->cap = SANE_CAP_SOFT_SELECT;
748   options[i]->constraint_type = SANE_CONSTRAINT_NONE;
749   values[i] = &height;
750   i++;
751 
752   options[i] =
753     (SANE_Option_Descriptor *) malloc (sizeof (SANE_Option_Descriptor));
754   options[i]->name = "array-of-fixed";
755   options[i]->title = "array of fixed";
756   options[i]->type = SANE_TYPE_FIXED;
757   options[i]->unit = SANE_UNIT_NONE;
758   options[i]->size = sizeof (fixedarray);
759   options[i]->cap = SANE_CAP_SOFT_SELECT;
760   options[i]->constraint_type = SANE_CONSTRAINT_RANGE;
761   options[i]->constraint.range = &height_range;
762   values[i] = fixedarray;
763   i++;
764 
765   config.descriptors = options;
766   config.values = values;
767   config.count = i;
768 
769   /* configure and attach */
770   status =
771     sanei_configure_attach (CONFIG_PATH "/data/fixed.conf",
772                             &config, check_config_attach, NULL);
773 
774   /* check results */
775   assert (status == SANE_STATUS_GOOD);
776   assert (width == SANE_FIX (21.0));
777   assert (height == SANE_FIX (29.7));
778   for (i = 0; i < 7; i++)
779     {
780       assert (fixedarray[i] == SANE_FIX (2.0 + 0.1 * ((float) i)));
781     }
782 }
783 
784 
785 /*
786  * fixed option with value out of range
787  */
788 static void
wrong_fixed_option(void)789 wrong_fixed_option (void)
790 {
791   SANE_Status status;
792   SANEI_Config config;
793   SANE_Word height;
794   SANE_Option_Descriptor *options[1];
795   void *values[1];
796   int i;
797 
798   i = 0;
799   options[i] =
800     (SANE_Option_Descriptor *) malloc (sizeof (SANE_Option_Descriptor));
801   options[i]->name = "height";
802   options[i]->title = "height";
803   options[i]->type = SANE_TYPE_FIXED;
804   options[i]->unit = SANE_UNIT_NONE;
805   options[i]->size = sizeof (SANE_Word);
806   options[i]->cap = SANE_CAP_SOFT_SELECT;
807   options[i]->constraint_type = SANE_CONSTRAINT_RANGE;
808   options[i]->constraint.range = &height_range;
809   values[i] = &height;
810   i++;
811 
812   config.descriptors = options;
813   config.values = values;
814   config.count = i;
815 
816   /* configure and attach */
817   status =
818     sanei_configure_attach (CONFIG_PATH "/data/wrong-fixed.conf",
819                             &config, check_config_attach, NULL);
820 
821   /* check results */
822   assert (status == SANE_STATUS_INVAL);
823 }
824 
825 
826 static void
snapscan(void)827 snapscan (void)
828 {
829   SANE_Status status;
830   SANEI_Config config;
831   SANE_Char firmware[128];
832   SANE_Option_Descriptor *options[1];
833   void *values[1];
834   int i;
835 
836   i = 0;
837   options[i] =
838     (SANE_Option_Descriptor *) malloc (sizeof (SANE_Option_Descriptor));
839   options[i]->name = "firmware";
840   options[i]->title = "scanner's firmware path";
841   options[i]->desc = "user provided scanner's full path";
842   options[i]->type = SANE_TYPE_STRING;
843   options[i]->unit = SANE_UNIT_NONE;
844   options[i]->size = sizeof (firmware);
845   options[i]->cap = SANE_CAP_SOFT_SELECT;
846   options[i]->constraint_type = SANE_CONSTRAINT_NONE;
847   values[i] = firmware;
848   i++;
849 
850   config.descriptors = options;
851   config.values = values;
852   config.count = i;
853 
854   /* configure and attach */
855   status =
856     sanei_configure_attach (CONFIG_PATH "/data/snapscan.conf",
857                             &config, check_config_attach, NULL);
858 
859   /* check results */
860   assert (status == SANE_STATUS_GOOD);
861   assert (strcmp (firmware, "/usr/share/sane/snapscan/your-firmwarefile.bin")
862 	  == 0);
863   /* TODO must test attach() done */
864 }
865 
866 
867 /**
868  * create the test suite for sanei config related tests
869  */
870 static void
sanei_config_suite(void)871 sanei_config_suite (void)
872 {
873   /* tests */
874   inexistent_config ();
875   empty_config ();
876   null_config ();
877   null_attach ();
878   string_option ();
879   int_option ();
880   string_list_option ();
881   word_array_option ();
882   bool_option ();
883   fixed_option ();
884   wrong_range_int_option ();
885   wrong_string_list_option ();
886   wrong_bool_option ();
887   wrong_fixed_option ();
888 
889   /* backend real conf inspired cases */
890   umax_pp ();
891   snapscan ();
892 }
893 
894 /**
895  * main function to run the test suites
896  */
897 int
main(void)898 main (void)
899 {
900   /* set up config dir for local conf files */
901   putenv("SANE_CONFIG_DIR=.:/");
902 
903   /* run suites */
904   sanei_config_suite ();
905 
906   return 0;
907 }
908 
909 /* vim: set sw=2 cino=>2se-1sn-1s{s^-1st0(0u0 smarttab expandtab: */
910