diff options
Diffstat (limited to 'backend/test.c')
| -rw-r--r-- | backend/test.c | 198 | 
1 files changed, 167 insertions, 31 deletions
| diff --git a/backend/test.c b/backend/test.c index a1e186e..075fdfa 100644 --- a/backend/test.c +++ b/backend/test.c @@ -17,9 +17,7 @@     General Public License for more details.     You should have received a copy of the GNU General Public License -   along with this program; if not, write to the Free Software -   Foundation, Inc., 59 Temple Place - Suite 330, Boston, -   MA 02111-1307, USA. +   along with this program.  If not, see <https://www.gnu.org/licenses/>.     As a special exception, the authors of SANE give permission for     additional uses of the libraries contained in this release of SANE. @@ -237,35 +235,34 @@ static SANE_String_Const source_list[] = {  static double random_factor;	/* use for fuzzyness of parameters */ -/* initial values */ +/* initial values. Initial string values are set in sane_init() */  static SANE_Word init_number_of_devices = 2;  static SANE_Fixed init_tl_x = SANE_FIX (0.0);  static SANE_Fixed init_tl_y = SANE_FIX (0.0);  static SANE_Fixed init_br_x = SANE_FIX (80.0);  static SANE_Fixed init_br_y = SANE_FIX (100.0);  static SANE_Word init_resolution = 50; -static SANE_String init_mode =SANE_VALUE_SCAN_MODE_GRAY; +static SANE_String init_mode = NULL;  static SANE_Word init_depth = 8;  static SANE_Bool init_hand_scanner = SANE_FALSE;  static SANE_Bool init_three_pass = SANE_FALSE; -static SANE_String init_three_pass_order = "RGB"; -static SANE_String init_scan_source = "Flatbed"; -static SANE_String init_test_picture = "Solid black"; +static SANE_String init_three_pass_order = NULL; +static SANE_String init_scan_source = NULL; +static SANE_String init_test_picture = NULL;  static SANE_Bool init_invert_endianess = SANE_FALSE;  static SANE_Bool init_read_limit = SANE_FALSE;  static SANE_Word init_read_limit_size = 1;  static SANE_Bool init_read_delay = SANE_FALSE;  static SANE_Word init_read_delay_duration = 1000; -static SANE_String init_read_status_code = "Default"; +static SANE_String init_read_status_code = NULL;  static SANE_Bool init_fuzzy_parameters = SANE_FALSE;  static SANE_Word init_ppl_loss = 0;  static SANE_Bool init_non_blocking = SANE_FALSE;  static SANE_Bool init_select_fd = SANE_FALSE;  static SANE_Bool init_enable_test_options = SANE_FALSE; -static SANE_String init_string = "This is the contents of the string option. " -  "Fill some more words to see how the frontend behaves."; -static SANE_String init_string_constraint_string_list = "First entry"; -static SANE_String init_string_constraint_long_string_list = "First entry"; +static SANE_String init_string = NULL; +static SANE_String init_string_constraint_string_list = NULL; +static SANE_String init_string_constraint_long_string_list = NULL;  /* Test if this machine is little endian (from coolscan.c) */  static SANE_Bool @@ -320,6 +317,38 @@ check_handle (SANE_Handle handle)    return SANE_FALSE;  } +static void +cleanup_options (Test_Device * test_device) +{ +  DBG (2, "cleanup_options: test_device=%p\n", (void *) test_device); + +  free(test_device->val[opt_mode].s); +  test_device->val[opt_mode].s = NULL; + +  free(test_device->val[opt_three_pass_order].s); +  test_device->val[opt_three_pass_order].s = NULL; + +  free(test_device->val[opt_scan_source].s); +  test_device->val[opt_scan_source].s = NULL; + +  free(test_device->val[opt_test_picture].s); +  test_device->val[opt_test_picture].s = NULL; + +  free(test_device->val[opt_read_status_code].s); +  test_device->val[opt_read_status_code].s = NULL; + +  free(test_device->val[opt_string].s); +  test_device->val[opt_string].s = NULL; + +  free(test_device->val[opt_string_constraint_string_list].s); +  test_device->val[opt_string_constraint_string_list].s = NULL; + +  free(test_device->val[opt_string_constraint_long_string_list].s); +  test_device->val[opt_string_constraint_long_string_list].s = NULL; + +  test_device->options_initialized = SANE_FALSE; +} +  static SANE_Status  init_options (Test_Device * test_device)  { @@ -368,7 +397,7 @@ init_options (Test_Device * test_device)    od->constraint.string_list = mode_list;    test_device->val[opt_mode].s = malloc (od->size);    if (!test_device->val[opt_mode].s) -    return SANE_STATUS_NO_MEM; +    goto fail;    strcpy (test_device->val[opt_mode].s, init_mode);    /* opt_depth */ @@ -435,7 +464,7 @@ init_options (Test_Device * test_device)    od->constraint.string_list = order_list;    test_device->val[opt_three_pass_order].s = malloc (od->size);    if (!test_device->val[opt_three_pass_order].s) -    return SANE_STATUS_NO_MEM; +    goto fail;    strcpy (test_device->val[opt_three_pass_order].s, init_three_pass_order);    /* opt_resolution */ @@ -464,7 +493,7 @@ init_options (Test_Device * test_device)    od->constraint.string_list = source_list;    test_device->val[opt_scan_source].s = malloc (od->size);    if (!test_device->val[opt_scan_source].s) -    return SANE_STATUS_NO_MEM; +    goto fail;    strcpy (test_device->val[opt_scan_source].s, init_scan_source);    /* opt_special_group */ @@ -500,7 +529,7 @@ init_options (Test_Device * test_device)    od->constraint.string_list = test_picture_list;    test_device->val[opt_test_picture].s = malloc (od->size);    if (!test_device->val[opt_test_picture].s) -    return SANE_STATUS_NO_MEM; +    goto fail;    strcpy (test_device->val[opt_test_picture].s, init_test_picture);    /* opt_invert_endianness */ @@ -595,7 +624,7 @@ init_options (Test_Device * test_device)    od->constraint.string_list = read_status_code_list;    test_device->val[opt_read_status_code].s = malloc (od->size);    if (!test_device->val[opt_read_status_code].s) -    return SANE_STATUS_NO_MEM; +    goto fail;    strcpy (test_device->val[opt_read_status_code].s, init_read_status_code);    /* opt_ppl_loss */ @@ -1129,7 +1158,7 @@ init_options (Test_Device * test_device)    od->constraint.string_list = 0;    test_device->val[opt_string].s = malloc (od->size);    if (!test_device->val[opt_string].s) -    return SANE_STATUS_NO_MEM; +    goto fail;    strcpy (test_device->val[opt_string].s, init_string);    /* opt_string_constraint_string_list */ @@ -1148,7 +1177,7 @@ init_options (Test_Device * test_device)    od->constraint.string_list = string_constraint_string_list;    test_device->val[opt_string_constraint_string_list].s = malloc (od->size);    if (!test_device->val[opt_string_constraint_string_list].s) -    return SANE_STATUS_NO_MEM; +    goto fail;    strcpy (test_device->val[opt_string_constraint_string_list].s,  	  init_string_constraint_string_list); @@ -1169,7 +1198,7 @@ init_options (Test_Device * test_device)    test_device->val[opt_string_constraint_long_string_list].s =      malloc (od->size);    if (!test_device->val[opt_string_constraint_long_string_list].s) -    return SANE_STATUS_NO_MEM; +    goto fail;    strcpy (test_device->val[opt_string_constraint_long_string_list].s,  	  init_string_constraint_long_string_list); @@ -1202,6 +1231,43 @@ init_options (Test_Device * test_device)    test_device->val[opt_button].w = 0;    return SANE_STATUS_GOOD; + +fail: +  cleanup_options (test_device); +  return SANE_STATUS_NO_MEM; +} + +static void +cleanup_initial_string_values () +{ +  // Cleanup backing memory for initial values of string options. +  free (init_mode); +  init_mode = NULL; +  free (init_three_pass_order); +  init_three_pass_order = NULL; +  free (init_scan_source); +  init_scan_source = NULL; +  free (init_test_picture); +  init_test_picture = NULL; +  free (init_read_status_code); +  init_read_status_code = NULL; +  free (init_string); +  init_string = NULL; +  free (init_string_constraint_string_list); +  init_string_constraint_string_list = NULL; +  free (init_string_constraint_long_string_list); +  init_string_constraint_long_string_list = NULL; +} + +static void +cleanup_test_device (Test_Device * test_device) +{ +  DBG (2, "cleanup_test_device: test_device=%p\n", (void *) test_device); +  if (test_device->options_initialized) +    cleanup_options (test_device); +  if (test_device->name) +    free (test_device->name); +  free (test_device);  }  static SANE_Status @@ -1331,7 +1397,11 @@ read_option (SANE_String line, SANE_String option_string,  	  {  	    DBG (3, "read_option: set option `%s' to `%s'\n", option_string,  		 word); +	    if (*(SANE_String *) value) +	      free (*(SANE_String *) value);  	    *(SANE_String *) value = strdup (word); +	    if (!*(SANE_String *) value) +	      return SANE_STATUS_NO_MEM;  	  }  	break;        } @@ -1575,6 +1645,49 @@ sane_init (SANE_Int * __sane_unused__ version_code, SANE_Auth_Callback __sane_un    if (inited)      DBG (3, "sane_init: warning: already inited\n"); +  // Setup initial values of string options. Call free initially in case we've +  // already called sane_init and these values are already non-null. +  free (init_mode); +  init_mode = strdup (SANE_VALUE_SCAN_MODE_GRAY); +  if (!init_mode) +    goto fail; + +  free (init_three_pass_order); +  init_three_pass_order = strdup ("RGB"); +  if (!init_three_pass_order) +    goto fail; + +  free (init_scan_source); +  init_scan_source = strdup ("Flatbed"); +  if (!init_scan_source) +    goto fail; + +  free (init_test_picture); +  init_test_picture = strdup ("Solid black"); +  if (!init_test_picture) +    goto fail; + +  free (init_read_status_code); +  init_read_status_code = strdup ("Default"); +  if (!init_read_status_code) +    goto fail; + +  free (init_string); +  init_string = strdup ("This is the contents of the string option. " +    "Fill some more words to see how the frontend behaves."); +  if (!init_string) +    goto fail; + +  free (init_string_constraint_string_list); +  init_string_constraint_string_list = strdup ("First entry"); +  if (!init_string_constraint_string_list) +    goto fail; + +  free (init_string_constraint_long_string_list); +  init_string_constraint_long_string_list = strdup ("First entry"); +  if (!init_string_constraint_long_string_list) +    goto fail; +    fp = sanei_config_open (TEST_CONFIG_FILE);    if (fp)      { @@ -1713,14 +1826,14 @@ sane_init (SANE_Int * __sane_unused__ version_code, SANE_Auth_Callback __sane_un    sane_device_list =      malloc ((init_number_of_devices + 1) * sizeof (sane_device));    if (!sane_device_list) -    return SANE_STATUS_NO_MEM; +    goto fail;    for (num = 0; num < init_number_of_devices; num++)      {        SANE_Char number_string[PATH_MAX]; -      test_device = malloc (sizeof (*test_device)); +      test_device = calloc (sizeof (*test_device), 1);        if (!test_device) -	return SANE_STATUS_NO_MEM; +	goto fail_device;        test_device->sane.vendor = "Noname";        test_device->sane.type = "virtual device";        test_device->sane.model = "frontend-tester"; @@ -1728,7 +1841,7 @@ sane_init (SANE_Int * __sane_unused__ version_code, SANE_Auth_Callback __sane_un        number_string[sizeof (number_string) - 1] = '\0';        test_device->name = strdup (number_string);        if (!test_device->name) -	return SANE_STATUS_NO_MEM; +	goto fail_name;        test_device->sane.name = test_device->name;        if (previous_device)  	previous_device->next = test_device; @@ -1740,6 +1853,7 @@ sane_init (SANE_Int * __sane_unused__ version_code, SANE_Auth_Callback __sane_un        test_device->eof = SANE_FALSE;        test_device->scanning = SANE_FALSE;        test_device->cancelled = SANE_FALSE; +      test_device->options_initialized = SANE_FALSE;        sanei_thread_initialize (test_device->reader_pid);        test_device->pipe = -1;        DBG (4, "sane_init: new device: `%s' is a %s %s %s\n", @@ -1752,6 +1866,25 @@ sane_init (SANE_Int * __sane_unused__ version_code, SANE_Auth_Callback __sane_un    random_factor = ((double) rand ()) / RAND_MAX + 0.5;    inited = SANE_TRUE;    return SANE_STATUS_GOOD; + +fail_name: +  // test_device refers to the last device we were creating, which has not +  // yet been added to the linked list of devices. +  free (test_device); +fail_device: +  // Now, iterate through the linked list of devices to clean up any successful +  // devices. +  test_device = first_test_device; +  while (test_device) +    { +      previous_device = test_device; +      test_device = test_device->next; +      cleanup_test_device (previous_device); +    } +  free (sane_device_list); +fail: +  cleanup_initial_string_values (); +  return SANE_STATUS_NO_MEM;  }  void @@ -1772,15 +1905,15 @@ sane_exit (void)        DBG (4, "sane_exit: freeing device %s\n", test_device->name);        previous_device = test_device;        test_device = test_device->next; -      if (previous_device->name) -	free (previous_device->name); -      free (previous_device); +      cleanup_test_device (previous_device);      }    DBG (4, "sane_exit: freeing device list\n");    if (sane_device_list)      free (sane_device_list);    sane_device_list = NULL;    first_test_device = NULL; + +  cleanup_initial_string_values ();    inited = SANE_FALSE;    return;  } @@ -1855,9 +1988,12 @@ sane_open (SANE_String_Const devicename, SANE_Handle * handle)    test_device->open = SANE_TRUE;    *handle = test_device; -  status = init_options (test_device); -  if (status != SANE_STATUS_GOOD) -    return status; +  if (!test_device->options_initialized) { +    status = init_options (test_device); +    if (status != SANE_STATUS_GOOD) +      return status; +    test_device->options_initialized = SANE_TRUE; +  }    test_device->open = SANE_TRUE;    test_device->scanning = SANE_FALSE; | 
