]> sigrok.org Git - libsigrok.git/commitdiff
sr_init(): Add driver sanity checks.
authorUwe Hermann <redacted>
Sun, 11 Nov 2012 22:54:49 +0000 (23:54 +0100)
committerUwe Hermann <redacted>
Sun, 2 Dec 2012 16:14:45 +0000 (17:14 +0100)
After sr_init() has successfully run, we can be sure that all drivers
define all the API calls, so we don't have to do these checks later
in the individual API functions / wrappers.

If there are one or more drivers with missing API functions (or driver
name / longname, and so on), sr_init() will fail. This helps catch this
kind of developer error early on.

backend.c

index 4823044efce580dbc9d7a116f1eb46e63a84a389..22f65a7c515174a6513c2f7d7c34d2fdb2584c74 100644 (file)
--- a/backend.c
+++ b/backend.c
  * @{
  */
 
+/**
+ * Sanity-check all libsigrok drivers.
+ *
+ * @return SR_OK if all drivers are OK, SR_ERR if one or more have issues.
+ */
+static int sanity_check_all_drivers(void)
+{
+       int i, errors, ret = SR_OK;
+       struct sr_dev_driver **drivers;
+       const char *d;
+
+       sr_spew("Sanity-checking all drivers.");
+
+       drivers = sr_driver_list();
+       for (i = 0; drivers[i]; i++) {
+               errors = 0;
+
+               d = (drivers[i]->name) ? drivers[i]->name : "NULL";
+
+               if (!drivers[i]->name) {
+                       sr_err("No name in driver %d ('%s').", i, d);
+                       errors++;
+               }
+               if (!drivers[i]->longname) {
+                       sr_err("No longname in driver %d ('%s').", i, d);
+                       errors++;
+               }
+               if (drivers[i]->api_version < 1) {
+                       sr_err("API version in driver %d ('%s') < 1.", i, d);
+                       errors++;
+               }
+               if (!drivers[i]->init) {
+                       sr_err("No init in driver %d ('%s').", i, d);
+                       errors++;
+               }
+               if (!drivers[i]->cleanup) {
+                       sr_err("No cleanup in driver %d ('%s').", i, d);
+                       errors++;
+               }
+               if (!drivers[i]->scan) {
+                       sr_err("No scan in driver %d ('%s').", i, d);
+                       errors++;
+               }
+               if (!drivers[i]->dev_list) {
+                       sr_err("No dev_list in driver %d ('%s').", i, d);
+                       errors++;
+               }
+               if (!drivers[i]->dev_clear) {
+                       sr_err("No dev_clear in driver %d ('%s').", i, d);
+                       errors++;
+               }
+               if (!drivers[i]->dev_open) {
+                       sr_err("No dev_open in driver %d ('%s').", i, d);
+                       errors++;
+               }
+               if (!drivers[i]->dev_close) {
+                       sr_err("No dev_close in driver %d ('%s').", i, d);
+                       errors++;
+               }
+               if (!drivers[i]->info_get) {
+                       sr_err("No info_get in driver %d ('%s').", i, d);
+                       errors++;
+               }
+               if (!drivers[i]->dev_config_set) {
+                       sr_err("No dev_config_set in driver %d ('%s').", i, d);
+                       errors++;
+               }
+               if (!drivers[i]->dev_acquisition_start) {
+                       sr_err("No dev_acquisition_start in driver %d ('%s').",
+                              i, d);
+                       errors++;
+               }
+               if (!drivers[i]->dev_acquisition_stop) {
+                       sr_err("No dev_acquisition_stop in driver %d ('%s').",
+                              i, d);
+                       errors++;
+               }
+
+               /* Note: 'priv' is allowed to be NULL. */
+
+               if (errors == 0)
+                       continue;
+
+               ret = SR_ERR;
+       }
+
+       return ret;
+}
+
 /**
  * Initialize libsigrok.
  *
@@ -138,6 +227,11 @@ SR_API int sr_init(struct sr_context **ctx)
                return SR_ERR;
        }
 
+       if (sanity_check_all_drivers() < 0) {
+               sr_err("Internal driver error(s), aborting.");
+               return ret;
+       }
+
        /* + 1 to handle when struct sr_context has no members. */
        context = g_try_malloc0(sizeof(struct sr_context) + 1);