]> sigrok.org Git - libsigrok.git/blobdiff - backend.c
add VID:PID for generic SILabs F32x USBXpress chips
[libsigrok.git] / backend.c
index 840b1723df9fea38ee755e2ee4ada1a2a258d48d..22f65a7c515174a6513c2f7d7c34d2fdb2584c74 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -19,6 +19,7 @@
  */
 
 #include <glib.h>
+#include "config.h" /* Needed for HAVE_LIBUSB_1_0 and others. */
 #include "libsigrok.h"
 #include "libsigrok-internal.h"
 
  * <a href="http://sigrok.org/wiki/Input_output_formats">input/output
  * file formats</a>.
  *
- * @section sec_error_handling Error handling
+ * @section sec_api API reference
  *
- * libsigrok functions usually return @ref SR_OK upon success, or a negative
- * error code on failure.
+ * See the "Modules" page for an introduction to various libsigrok
+ * related topics and the detailed API documentation of the respective
+ * functions.
+ *
+ * You can also browse the API documentation by file, or review all
+ * data structures.
  *
  * @section sec_mailinglists Mailing lists
  *
  * <a href="http://sigrok.org/wiki/Libsigrok">sigrok.org/wiki/Libsigrok</a>
  */
 
+/**
+ * @file
+ *
+ * Initializing and shutting down libsigrok.
+ */
+
 /**
  * @defgroup grp_init Initialization
  *
  * Initializing and shutting down libsigrok.
  *
+ * Before using any of the libsigrok functionality, sr_init() must
+ * be called to initialize the library, which will return a struct sr_context
+ * when the initialization was successful.
+ *
+ * When libsigrok functionality is no longer needed, sr_exit() should be
+ * called, which will (among other things) free the struct sr_context.
+ *
+ * Example for a minimal program using libsigrok:
+ *
+ * @code{.c}
+ *   #include <stdio.h>
+ *   #include <libsigrok/libsigrok.h>
+ *
+ *   int main(int argc, char **argv)
+ *   {
+ *     int ret;
+ *     struct sr_context *sr_ctx;
+ *
+ *     if ((ret = sr_init(&sr_ctx)) != SR_OK) {
+ *             printf("Error initializing libsigrok (%s): %s.",
+ *                    sr_strerror_name(ret), sr_strerror(ret));
+ *             return 1;
+ *     }
+ *
+ *     // Use libsigrok functions here...
+ *
+ *     if ((ret = sr_exit(sr_ctx)) != SR_OK) {
+ *             printf("Error shutting down libsigrok (%s): %s.",
+ *                    sr_strerror_name(ret), sr_strerror(ret));
+ *             return 1;
+ *     }
+ *
+ *     return 0;
+ *   }
+ * @endcode
+ *
  * @{
  */
 
+/**
+ * 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.
  *
@@ -91,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);