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; |