...
 
Commits (36)
......@@ -2,17 +2,19 @@ image: fedora:rawhide
stages:
- build
- test
- flatpack
variables:
DEPENDENCIES: libusb1-devel glib2-devel nss-devel pixman-devel systemd meson gtk-doc
DEPENDENCIES: libgusb-devel glib2-devel nss-devel pixman-devel systemd meson gtk-doc
gcc gcc-c++ glibc-devel libX11-devel libXv-devel gtk3-devel flatpak-builder
gobject-introspection-devel python3-cairo python3-gobject
BUNDLE: "org.freedesktop.libfprint.Demo.flatpak"
.build_one_driver_template: &build_one_driver
script:
- dnf update -y --nogpgcheck && dnf install -y --nogpgcheck $DEPENDENCIES
# Build with a driver that doesn't need imaging, or nss
- meson -Ddrivers=elan . _build
- meson -Ddrivers=$driver . _build
- ninja -C _build
- rm -rf _build/
......@@ -26,9 +28,19 @@ variables:
build:
stage: build
variables:
driver: virtual_image
<<: *build_one_driver
<<: *build
test:
stage: test
script:
- dnf update -y --nogpgcheck && dnf install -y --nogpgcheck $DEPENDENCIES
- meson -Ddrivers=virtual_image . _build
- ninja -C _build
- meson test -C _build --verbose --no-stdsplit
.flatpak_script_template: &flatpak_script
script:
- flatpak-builder --stop-at=${FLATPAK_MODULE} app ${MANIFEST_PATH}
......@@ -53,8 +65,8 @@ build:
<<: *flatpak_artifacts
flatpak master:
image: registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:master
stage: test
image: registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:3.32
stage: flatpack
variables:
MANIFEST_PATH: "demo/org.freedesktop.libfprint.Demo.json"
# From demo/org.freedesktop.libfprint.Demo.json
......
// Remove USB device reset, lets hope that we do not need this.
// If we do, maybe do it elsewhere?
@@
identifier r;
@@
- r = libusb_reset_device(...);
- if (r != 0) { ... }
// Functions that have uneccessary returns (i.e. error cannot happen after refactoring)
// NOTE: Make sure that these function are fine to modify in *all* drivers!
@ prior_int_func @
identifier func =~ "capture_chunk_async|alksdjflkajsfd";
expression res, res2;
@@
-int func
+void func
(...)
{
<...
- return res2;
+ res2;
...>
- return res;
+ res;
}
@@
identifier prior_int_func.func;
identifier res;
@@
-res = func
+func
(...);
(
-if (res < 0) { ... }
|
-if (res != 0) { ... }
)
// Remove useless checks of fpi_timeout_add return values
@@
expression a1, a2, a3, a4;
@@
-if (fpi_timeout_add(a1, a2, a3, a4) == NULL) { ... }
+fpi_timeout_add(a1, a2, a3, a4);
@@
identifier timeout;
expression a1, a2, a3, a4;
@@
timeout = fpi_timeout_add(a1, a2, a3, a4);
-if (timeout == NULL) { ... }
// The VFS5011 driver has some stupid "radiation detected" logic, that should be asserts
@@
expression expr;
@@
-if ((expr)) {
- ...
- fp_err("Radiation detected!");
- ...
-}
+g_assert(!expr);
// A number of drivers call both fpi_imgdev_session_error *and* fpi_ssm_mark_failed.
// While this worked fine, it is plain wrong and considerably complicates memory
// management of the errors.
// Remove this duplication
@@
expression dev;
expression ssm;
expression error;
@@
- fpi_imgdev_session_error(dev, error);
fpi_ssm_mark_failed(ssm, error);
@@
@@
- LIBUSB_ENDPOINT_IN
+ FP_USB_ENDPOINT_IN
@@
@@
- LIBUSB_ENDPOINT_OUT
+ FP_USB_ENDPOINT_OUT
@ fp_img_dev @
typedef FpImageDevice;
@@
-struct fp_img_dev
+FpImageDevice
@ FpImageDevice_cast @
typedef FpImageDevice;
expression dev;
@@
-(FpImageDevice*) dev
+FP_IMAGE_DEVICE (dev)
@ fp_dev @
typedef FpDevice;
@@
-struct fp_dev
+FpDevice
@ FpDevice_cast @
typedef FpDevice;
expression dev;
@@
-(FpDevice*) dev
+FP_DEVICE (dev)
@ FP_DEV_cast @
expression dev;
@@
- FP_DEV (dev)
+ FP_DEVICE (dev)
@ FP_IMG_DEV_cast @
expression dev;
@@
- FP_IMG_DEV (dev)
+ FP_IMAGE_DEVICE (dev)
@ fpi_ssm @
typedef fpi_ssm;
typedef FpSsm;
@@
-fpi_ssm
+FpSsm
@ fp_img @
typedef FpImage;
@@
-struct fp_img
+FpImage
@ libusb_transfer @
typedef FpUsbTransfer;
@@
-struct libusb_transfer
+FpUsbTransfer
@ libusb_device_handle @
typedef libusb_device_handle;
typedef GUsbDevice;
@@
-libusb_device_handle
+GUsbDevice
@@
expression w;
expression h;
expression status;
expression dev;
expression a1, a2, a3;
@@
(
-fpi_img_new(w * h)
+fp_image_new(w, h)
|
-fpi_ssm_new
+fp_ssm_new
|
-fpi_ssm_free
+fp_ssm_free
|
-fpi_ssm_start
+fp_ssm_start
|
-fpi_ssm_start_subsm
+fp_ssm_start_subsm
|
-fpi_ssm_next_state
+fp_ssm_next_state
|
-fpi_ssm_jump_to_state
+fp_ssm_jump_to_state
|
-fpi_ssm_mark_completed
+fp_ssm_mark_completed
|
-fpi_ssm_get_user_data
+fp_ssm_get_user_data
|
-fpi_ssm_get_cur_state
+fp_ssm_get_cur_state
|
-fpi_dev_get_usb_dev
+_fp_device_get_usb_device
|
// HACK: We just insert an error return here!
-fpi_imgdev_close_complete(dev)
+_fp_image_device_close_complete(dev, error)
|
-fpi_imgdev_open_complete(dev, 0)
+_fp_image_device_open_complete(dev, NULL)
|
-fpi_imgdev_activate_complete(dev, 0)
+_fp_image_device_activate_complete(dev, NULL)
|
-fpi_imgdev_deactivate_complete(dev)
+_fp_image_device_deactivate_complete(dev, NULL)
|
-fpi_imgdev_report_finger_status(dev, status)
+_fp_image_device_report_finger_status(dev, status)
|
-fpi_imgdev_image_captured(dev, a1)
+_fp_image_device_image_captured(dev, a1)
|
-fpi_imgdev_abort_scan
+_fp_image_device_retry_scan
|
-fpi_std_sq_dev
+_fp_std_sq_dev
|
-fpi_mean_sq_diff_norm
+_fp_mean_sq_diff_norm
|
-fpi_timeout_add(a1, a2, dev, a3)
+_fp_device_add_timeout(dev, a1, a2, a3)
)
// Some can be nested
@@
@@
(
-fpi_ssm_next_state_timeout_cb
+fp_ssm_next_state_timeout_cb
)
@@
typedef FpImageDeviceState;
@@
(
-FP_IMG_COLORS_INVERTED
+FP_IMAGE_COLORS_INVERTED
|
-FP_IMG_H_FLIPPED
+FP_IMAGE_H_FLIPPED
|
-FP_IMG_V_FLIPPED
+FP_IMAGE_V_FLIPPED
|
-FP_VERIFY_RETRY_TOO_SHORT
+FP_DEVICE_RETRY_TOO_SHORT
|
-FP_VERIFY_RETRY_CENTER_FINGER
+FP_DEVICE_RETRY_CENTER_FINGER
|
-FP_VERIFY_RETRY
+FP_DEVICE_RETRY
)
@@
@@
(
-enum fp_imgdev_state
+FpImageDeviceState
)
@ dev_func @
identifier dev;
identifier func;
@@
func(..., FpDevice *dev, ...)
{
...
}
@ imgdev_func @
identifier dev;
identifier func;
@@
func(..., FpImageDevice *dev, ...)
{
...
}
@ self_func extends driver @
identifier self;
identifier func;
@@
func(..., driver_cls *self, ...)
{
...
}
@ transfer_func_imgdev @
typedef FpUsbTransfer;
identifier imgdev_func.func;
identifier imgdev_func.dev;
identifier transfer;
@@
func (...)
{
<...
(
-transfer = fpi_usb_alloc();
+transfer = fp_usb_transfer_new(FP_DEVICE (dev));
|
-FpUsbTransfer *transfer = fpi_usb_alloc();
+FpUsbTransfer *transfer = fp_usb_transfer_new(FP_DEVICE (dev));
)
...>
}
@ transfer_func_dev @
typedef FpUsbTransfer;
identifier dev_func.func;
identifier dev_func.dev;
identifier transfer;
@@
func (...)
{
<...
(
-transfer = fpi_usb_alloc();
+transfer = fp_usb_transfer_new(dev);
|
-FpUsbTransfer *transfer = fpi_usb_alloc();
+FpUsbTransfer *transfer = fp_usb_transfer_new(dev);
)
...>
}
@ transfer_func_self @
typedef FpUsbTransfer;
identifier self_func.func;
identifier self_func.self;
expression transfer;
@@
func (...)
{
<...
-transfer = fpi_usb_alloc();
+transfer = fp_usb_transfer_new(FP_DEVICE (self));
...>
}
// None of the release interface calls had error handling ...
@ extends driver @
expression usb_dev;
expression interface;
@@
dev_close(...)
{
+ GError *error = NULL;
...
-libusb_release_interface(usb_dev, interface);
+g_usb_device_release_interface(usb_dev, interface, 0, &error);
...
}
@ extends driver @
expression usb_dev;
expression interface;
identifier imgdev;
identifier r;
@@
dev_open (..., FpImageDevice *imgdev, ...)
{
+ GError *error = NULL;
...
-r = libusb_claim_interface(usb_dev, interface);
+if (!g_usb_device_claim_interface(usb_dev, interface, 0, &error)) {
+ _fp_image_device_open_complete (imgdev, error);
+ return;
+ }
(
-if (r != 0) { ... }
|
-if (r < 0) { ... }
)
...
}
@ usb_transfer_cb @
typedef FpUsbTransfer;
typedef FpSsm;
identifier func;
identifier transfer;
identifier dev;
identifier ssm;
@@
(
-void func(FpUsbTransfer *transfer)
+void func(FpUsbTransfer *transfer,
+ FpDevice *device,
+ gpointer user_data,
+ GError *error)
{
...
}
|
// this is weird, one function in uru4000 didn't get the types
// converted by earlier rules. But, this does not seem to work either.
-void func(\(FpUsbTransfer*\|struct libusb_transfer*\) transfer,
- \(FpDevice*\|struct fp_dev*\) dev,
- \(FpSsm*\|fpi_ssm*\) ssm,
- void* user_data)
+void func(FpUsbTransfer *transfer,
+ FpDevice *dev,
+ gpointer user_data,
+ GError *error)
{
+ FpSsm *ssm = transfer->ssm;
...
}
)
@ errors_generic_1 @
identifier usb_transfer_cb.func;
identifier usb_transfer_cb.transfer;
@@
func(...)
{
<...
(
- (transfer->status != LIBUSB_TRANSFER_COMPLETED)
+ error
|
- (transfer->status == LIBUSB_TRANSFER_COMPLETED)
+ !error
|
- (transfer->status == LIBUSB_TRANSFER_TIMED_OUT)
+ g_error_matches (error, G_USB_DEVICE_ERROR, G_USB_DEVICE_ERROR_TIMED_OUT)
)
...>
}
@ errors_1 @
identifier usb_transfer_cb.func;
identifier usb_transfer_cb.transfer;
expression ssm;
statement S;
@@
func(...)
{
<...
if (error) {
(
...
- fpi_ssm_mark_failed (ssm, ...)
+ fp_ssm_mark_failed (ssm, error)
...
|
...
- fpi_imgdev_session_error (...)
+ _fp_image_device_session_error (FP_IMAGE_DEVICE (device), error)
...
)
}
...>
}
@ errors_1_alt @
identifier usb_transfer_cb.func;
identifier usb_transfer_cb.transfer;
expression ssm;
statement S;
@@
func(...)
{
<...
if (!error) { ... }
else {
(
...
- fpi_ssm_mark_failed (ssm, ...)
+ fp_ssm_mark_failed (ssm, error)
...
|
...
- fpi_imgdev_session_error (...)
+ _fp_image_device_session_error (FP_IMAGE_DEVICE (device), error)
...
)
}
...>
}
@ errors_2 @
identifier usb_transfer_cb.func;
identifier usb_transfer_cb.transfer;
expression ssm;
@@
func(...)
{
<...
if (transfer->length != transfer->actual_length) {
+ _Pragma("GCC warning \"Driver should probably set short_is_error instead!\"");
...
(
- fpi_ssm_mark_failed (ssm, ...);
+ fp_ssm_mark_failed (ssm, g_error_new (G_USB_DEVICE_ERROR,
+ G_USB_DEVICE_ERROR_IO,
+ "Short USB transfer!"));
|
- fpi_imgdev_session_error (...);
+ _fp_image_device_session_error (FP_IMAGE_DEVICE (device),
+ g_error_new (G_USB_DEVICE_ERROR,
+ G_USB_DEVICE_ERROR_IO,
+ "Short USB transfer!"));
)
...
}
...>
}
@ not_useful_error_prints @
identifier usb_transfer_cb.func;
@@
func(...)
{
<...
- fp_err (...);
...
(
fp_ssm_mark_failed (...);
|
_fp_image_device_session_error (...);
)
...>
}
@ error_or_wrong_length @
identifier usb_transfer_cb.func;
identifier usb_transfer_cb.transfer;
expression ssm;
@@
func(...)
{
<...
- if (error || (transfer->length != transfer->actual_length))
+ if (error)
{
+ _Pragma("GCC warning \"Driver needs to set short_is_error for this branch to be taken!\"");
<...
(
- fpi_ssm_mark_failed (ssm, ...);
+ fp_ssm_mark_failed (ssm, error);
|
- fpi_imgdev_session_error (...);
+ _fp_image_device_session_error (FP_IMAGE_DEVICE (device), error);
)
...>
}
...>
}
@ error_or_wrong_length_2 @
identifier usb_transfer_cb.func;
identifier usb_transfer_cb.transfer;
expression ssm;
@@
func(...)
{
<...
- if (!error && (transfer->length == transfer->actual_length))
+ if (!error)
{ ... }
else {
+ _Pragma("GCC warning \"Driver needs to set short_is_error for this branch to be taken!\"");
<...
(
- fpi_ssm_mark_failed (ssm, ...);
+ fp_ssm_mark_failed (ssm, error);
|
- fpi_imgdev_session_error (...);
+ _fp_image_device_session_error (FP_IMAGE_DEVICE (device), error);
)
...>
}
...>
}
@@
identifier usb_transfer_cb.func;
identifier usb_transfer_cb.transfer;
identifier out;
@@
func(...)
{
<...
- goto out;
+ return;
...>
-out:
(
- g_free(transfer->buffer);
|
)
- libusb_free_transfer (transfer);
}
@@
identifier usb_transfer_cb.func;
identifier usb_transfer_cb.transfer;
@@
func(...)
{
<...
(
- g_free(transfer->buffer);
|
)
- libusb_free_transfer (transfer);
...
return;
...>
}
@@
identifier usb_transfer_cb.func;
identifier usb_transfer_cb.transfer;
@@
func(...)
{
<...
- transfer->user_data
+ user_data
...>
}
@@
typedef gint;
identifier usb_transfer_cb.func;
identifier usb_transfer_cb.transfer;
@@
func(...)
{
<...
(
fp_dbg
|
fp_warn
|
fp_err
)
(...,
- transfer->length
+ (gint) transfer->length
, ...);
...>
}
@@
typedef gint;
identifier usb_transfer_cb.func;
identifier usb_transfer_cb.transfer;
@@
func(...)
{
<...
(
fp_dbg
|
fp_warn
|
fp_err
)
(...,
- transfer->actual_length
+ (gint) transfer->actual_length
, ...);
...>
}
@@
identifier usb_transfer_cb.func;
identifier usb_transfer_cb.transfer;
identifier ssm_var;
gpointer user_data;
@@
func(...)
{
...
(
- FpSsm *ssm_var = (FpSsm*) user_data;
|
- FpSsm *ssm_var = user_data;
)
<...
- ssm_var
+ transfer->ssm
...>
}
// A lot of drivers abuse the SSM user_data for the driver
// Convert FpImageDevice usage to simple cast
@@
identifier usb_transfer_cb.func;
identifier dev;
@@
func(...)
{
-FpImageDevice *dev = ...;
+FpImageDevice *dev = FP_IMAGE_DEVICE (device);
...
}
// A lot of drivers abuse the SSM user_data for the driver
// Remove FpDevice getter and use argument
@@
identifier usb_transfer_cb.func;
identifier arg;
identifier dev;
@@
func(..., FpDevice *arg, ...)
{
-FpDevice *dev = ...;
<...
-dev
+arg
...>
}
///////////////////////////////////////////////////////////////////////////
// bulk transfers
@@
typedef FpUsbTransfer;
expression transfer;
expression usb_dev;
expression endpoint;
expression data;
expression size;
expression cb;
expression user_data;
expression timeout;
identifier ret;
@@
- libusb_fill_bulk_transfer(transfer, usb_dev, endpoint, data, size, cb, user_data, timeout);
+ fp_usb_transfer_fill_bulk_full(transfer, endpoint, data, size, NULL);
+ fp_usb_transfer_submit(transfer, timeout, NULL, cb, user_data);
+ fp_usb_transfer_unref(transfer);
(
- ret = libusb_submit_transfer(transfer);
...
(
- if (ret < 0) { ... }
|
- if (ret != 0) { ... }
|
)
|
- if (libusb_submit_transfer(transfer)) { ... }
|
- if (libusb_submit_transfer(transfer) < 0) { ... }
|
- libusb_submit_transfer(transfer);
)
///////////////////////////////////////////////////////////////////////////
// bulk transfers
@@
typedef FpUsbTransfer;
expression transfer;
expression dev;
expression transfer_ssm;
expression endpoint;
expression data;
expression size;
expression cb;
expression user_data;
expression timeout;
expression storage;
identifier ret;
@@
- transfer = fpi_usb_fill_bulk_transfer(dev, transfer_ssm, endpoint, data, size, cb, user_data, timeout);
+ transfer = fp_usb_transfer_new (dev);
+ transfer->ssm = transfer_ssm;
+ fp_usb_transfer_fill_bulk_full(transfer, endpoint, data, size, NULL);
+ fp_usb_transfer_submit(transfer, timeout, NULL, cb, user_data);
+ fp_usb_transfer_unref(transfer);
(
storage = transfer;
|
)
(
- ret = fpi_usb_submit_transfer(transfer);
...
(
- if (ret < 0) { ... }
|
- if (ret != 0) { ... }
|
)
|
- if (fpi_usb_submit_transfer(transfer)) { ... }
|
- if (fpi_usb_submit_transfer(transfer) < 0) { ... }
|
- fpi_usb_submit_transfer(transfer);
)
// The following only happens due to some prior simplifications we did
@@
typedef FpUsbTransfer;
expression transfer;
expression usb_dev;
expression endpoint;
expression data;
expression size;
expression cb;
expression user_data;
expression timeout;
identifier ret;
@@
- libusb_fill_bulk_transfer(transfer, usb_dev, endpoint, data, size, cb, user_data, timeout);
- libusb_submit_transfer(transfer);
+ fp_usb_transfer_fill_bulk_full(transfer, endpoint, data, size, NULL);
+ fp_usb_transfer_submit(transfer, timeout, NULL, cb, user_data);
+ fp_usb_transfer_unref(transfer);
///////////////////////////////////////////////////////////////////////////
// control transfers
@@
typedef FpUsbTransfer;
expression timeout;
expression direction;
expression request_type;
expression recipient;
expression request;
expression value;
expression index;
expression length;
expression callback;
expression user_data;
expression usb_dev;
identifier ret;
@@
(
- data = g_malloc(LIBUSB_CONTROL_SETUP_SIZE)
|
- data = g_malloc(LIBUSB_CONTROL_SETUP_SIZE + ...)
|
- data = g_malloc0(LIBUSB_CONTROL_SETUP_SIZE)
|
- data = g_malloc0(LIBUSB_CONTROL_SETUP_SIZE + ...)
)
- ;
+ _Pragma("GCC warning \"control transfer filling is a mess due to automatic translation\"");
+ fp_usb_transfer_fill_control(transfer, !((request_type) & 0x80), ((request_type) >> 5) & 0x3, (request_type) & 0x1f, request, value, index, length);
+ data = transfer->buffer;
+ fp_usb_transfer_submit(transfer, timeout, NULL, callback, user_data);
+ fp_usb_transfer_unref(transfer);
...
- libusb_fill_control_setup(data, request_type, request, value, index, length);
- libusb_fill_control_transfer(transfer, usb_dev, data, callback, user_data, timeout);
<...
- LIBUSB_CONTROL_SETUP_SIZE
...>
- ret = libusb_submit_transfer(transfer);
(
- if (ret < 0) { ... }
|
)
///////////////////////////////////////////////////////////////////////////
// We have a field in the transfer just for a state machine, use that
// We also later modify all similar code on the callback side to use that field
// instead.
@@
expression transfer;
expression timeout;
expression cb;
@@
+ transfer->ssm = ssm;
- fp_usb_transfer_submit(transfer, timeout, NULL, cb, ssm);
+ fp_usb_transfer_submit(transfer, timeout, NULL, cb, NULL);
@@
expression transfer;
expression timeout;
expression cb;
@@
- fp_usb_transfer_submit(transfer, timeout, NULL, cb, dev);
+ fp_usb_transfer_submit(transfer, timeout, NULL, cb, NULL);
@ ssm_callbacks @
identifier ssm;
identifier cb;
@@
fp_ssm_start(ssm, cb)
@@
identifier ssm_callbacks.cb;
identifier ssm;
identifier dev;
identifier user_data;
@@
void cb(FpSsm *ssm, FpDevice *dev, void* user_data
+ , GError *error
)
{
+ _Pragma("GCC warning \"Check that error is returned/free'ed properly!\"");
...
}
@ orig_driver_struct @
identifier driver_struct;
@@
struct fp_img_driver driver_struct = {
...,
};
// Grab the type of the main device struct using a rather blind fashion,
// and remove it from the init function.
// This assume that only device init calls fp_dev_set_instance_data, which
// is a fair assumption after all
@ orig_device_struct @
type device_struct;
expression dev;
identifier dev_init;
identifier data;
@@
dev_init(...)
{
// Note: We redefine it to an instance access for now, which will be
// made to work correctly with a later transform/cast.
...
device_struct *data;
...
(
- data = g_malloc0(sizeof(*data));
+ data = FP_INSTANCE_DATA(dev);
|
- data = (device_struct*) g_malloc0(sizeof(*data));
+ data = FP_INSTANCE_DATA(dev);
|
- data = g_malloc0(sizeof(device_struct));
+ data = FP_INSTANCE_DATA(dev);
)
...
- fp_dev_set_instance_data(dev, data);
...
}
@ driver_ids @
typedef FpIdEntry;
identifier driver_id_table;
@@
-const struct usb_id driver_id_table[] = {
+const FpIdEntry driver_id_table[] = {
...
};
@ @
identifier driver_ids.driver_id_table;
expression entry_vid;
expression entry_pid;
@@
const FpIdEntry driver_id_table[] = {
..., {
- .vendor = entry_vid, .product = entry_pid,
+ .vid = entry_vid, .pid = entry_pid,
}, ...
};
@ @
identifier driver_ids.driver_id_table;
expression entry_vid;
expression entry_pid;
expression entry_data;
@@
const FpIdEntry driver_id_table[] = {
..., {
- .vendor = entry_vid, .product = entry_pid, .device_data = entry_data
+ .vid = entry_vid, .pid = entry_pid, .driver_data = entry_data
}, ...
};
@ @
identifier driver_ids.driver_id_table;
expression entry_vid;
expression entry_pid;
expression entry_data;
@@
const FpIdEntry driver_id_table[] = {
..., {
- entry_vid, entry_pid, entry_data
+ .vid = entry_vid, .pid = entry_pid, .driver_data = entry_data
}, ...
};
@ driver_info extends orig_driver_struct @
expression driver_full_name;
identifier driver_id_table;
identifier dev_open;
identifier dev_close;
identifier dev_scan_type;
@@
struct fp_img_driver driver_struct = {
.driver = {
.full_name = driver_full_name,
.id_table = driver_id_table,
.scan_type = dev_scan_type,
},
.open = dev_open,
.close = dev_close,
};
@ script:python driver_gobj @
driver_struct << orig_driver_struct.driver_struct;
driver_id;
driver_init;
driver_cls;
_driver_cls;
driver_klass;
driver_class_init;
driver_ns;
driver_cast;
driver_cast_no_prefix;
@@
import os
driver_id = driver_struct.split('_')[:-1]
driver_cls = "FpDevice" + "".join(d[0].upper() + d[1:] for d in driver_id)
driver_id = '_'.join(driver_id)
driver_ns = "fp_device_" + driver_id
driver_cast = driver_ns.upper()
driver_cast_no_prefix = driver_ns.upper()[3:]
coccinelle.driver_id = cocci.make_expr('"%s"' % driver_id)
coccinelle.driver_cls = cocci.make_type(driver_cls)
coccinelle._driver_cls = cocci.make_type('struct _' + driver_cls)
coccinelle.driver_klass = cocci.make_type(driver_cls + 'Class')
coccinelle.driver_ns = cocci.make_ident(driver_ns)
coccinelle.driver_init = cocci.make_ident(driver_ns + '_init')
coccinelle.driver_class_init = cocci.make_ident(driver_ns + '_class_init')
coccinelle.driver_cast = cocci.make_ident(driver_cast)
coccinelle.driver_cast_no_prefix = cocci.make_ident(driver_cast_no_prefix)
#############################################################################
@ driver @
typedef FpDeviceClass;
typedef FpImageDeviceClass;
type orig_device_struct.device_struct;
identifier orig_driver_struct.driver_struct;
expression driver_gobj.driver_id;
identifier driver_gobj.driver_ns;
identifier driver_gobj.driver_init;
identifier driver_gobj.driver_class_init;
identifier driver_gobj.driver_cast;
identifier driver_gobj.driver_cast_no_prefix;
type driver_gobj.driver_cls;
type driver_gobj._driver_cls;
type driver_gobj.driver_klass;
expression driver_info.driver_full_name;
identifier driver_info.driver_id_table;
identifier driver_info.dev_open;
identifier driver_info.dev_close;
identifier driver_info.dev_scan_type;
@@
struct fp_img_driver driver_struct = {
...
};
+static void
+driver_init(driver_cls *self)
+{
+}
+
+static void
+driver_class_init(driver_klass *klass)
+{
+ FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
+ FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_CLASS (klass);
+
+ dev_class->id = driver_id;
+ dev_class->full_name = driver_full_name;
+ dev_class->type = FP_DEVICE_TYPE_USB;
+ dev_class->id_table = driver_id_table;
+ dev_class->scan_type = dev_scan_type;
+
+ img_class->img_open = dev_open;
+ img_class->img_close = dev_close;
+ IMG_CLASS_FUNCS;
+}
/////////////////////////////////////////////////////////////////////////
@ optional_activate extends driver @
identifier dev_activate;
@@
struct fp_img_driver driver_struct = {
- .activate = dev_activate,
};
@@
identifier optional_activate.dev_activate;
@@
+ img_class->activate = dev_activate;
IMG_CLASS_FUNCS;
/////////////////////////////////////////////////////////////////////////
@ optional_deactivate extends driver @
identifier dev_deactivate;
@@
struct fp_img_driver driver_struct = {
- .deactivate = dev_deactivate,
};
@@
identifier optional_deactivate.dev_deactivate;
@@
+ img_class->deactivate = dev_deactivate;
IMG_CLASS_FUNCS;
/////////////////////////////////////////////////////////////////////////
@ optional_change_state extends driver @
identifier dev_change_state;
@@
struct fp_img_driver driver_struct = {
- .change_state = dev_change_state,
};
@@
identifier optional_change_state.dev_change_state;
@@
+ img_class->change_state = dev_change_state;
IMG_CLASS_FUNCS;
/////////////////////////////////////////////////////////////////////////
@ optional_bz3 extends driver @
expression dev_bz3_threshold;
@@
struct fp_img_driver driver_struct = {
- .bz3_threshold = dev_bz3_threshold,
};
@@
expression optional_bz3.dev_bz3_threshold;
@@
+
+ img_class->bz3_threshold = dev_bz3_threshold;
IMG_CLASS_FUNCS;
/////////////////////////////////////////////////////////////////////////
@ optional_img_size extends driver @
expression dev_img_width;
expression dev_img_height;
@@
struct fp_img_driver driver_struct = {
- .img_width = dev_img_width,
- .img_height = dev_img_height,
};
@@
expression optional_img_size.dev_img_width;
expression optional_img_size.dev_img_height;
@@
+
+ img_class->img_width = dev_img_width;
+ img_class->img_height = dev_img_height;
IMG_CLASS_FUNCS;
@ remove_placeholder extends driver @
@@
- IMG_CLASS_FUNCS;
@ remove_orig extends driver @
@@
-struct fp_img_driver driver_struct = {
- ...
-};
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
@ type_declaration extends driver @
@@
-device_struct {
+_driver_cls {
+ FpImageDevice parent;
+
...
};
+#include "TYPE_DECLARATION"
@ extends driver @
@@
-#include "TYPE_DECLARATION"
+G_DECLARE_FINAL_TYPE (driver_cls, driver_ns, FP, driver_cast_no_prefix, FpImageDevice);
+G_DEFINE_TYPE (driver_cls, driver_ns, FP_TYPE_IMAGE_DEVICE);
///////////////
// Change some function declarations
@ extends driver @
identifier a_driver_data;
@@
-int
+void
dev_open(...
- ,unsigned long a_driver_data
) { ... }
@ extends driver @
@@
-int
+void
dev_activate(...) { ... }
/////////////////////////////////////////////////////////////////////////
// Replace all old data with a cast to the new class
/////////////////////////////////////////////////////////////////////////
@ rewrite_dev_struct extends driver @
identifier func;
identifier data;
identifier dev;
@@
func(...)
{
...
(
- device_struct *data;
+ driver_cls *self;
...
(
- data = FP_INSTANCE_DATA(FP_DEVICE(dev));
+ data = driver_cast(dev);
|
- data = FP_INSTANCE_DATA(dev);
+ data = driver_cast(dev);
)
|
- device_struct *data = FP_INSTANCE_DATA(FP_DEVICE(dev));
+ driver_cls *self = driver_cast(dev);
|
- device_struct *data = FP_INSTANCE_DATA(dev);
+ driver_cls *self = driver_cast(dev);
)
...
}
@@
identifier rewrite_dev_struct.func;
identifier rewrite_dev_struct.data;
@@
func(...)
{
<...
- data
+ self
...>
}
@ extends driver @
identifier func;
identifier data;
@@
func(...,
- device_struct *data,
+ driver_cls *self,
...)
{
<...
- data
+ self
...>
}
// Remove unneccessary self check
@@
@@
-if (self != NULL) {
...
-}
// Remove g_free(self)
@@
@@
-g_free(self);
// If we have matches on error conditions, the we likely have a memory
// mangement error.
@ forall @
identifier error;
statement S;
@@
if (<+... g_error_matches(error, ...) ...+>) {
+ _Pragma ("GCC error \"Inserted possibly wrong g_error_free!\"");
+ if (error)
+ g_error_free (error);
...
} else S
@ forall @
identifier error;
@@
if (<+... g_error_matches(error, ...) ...+>) {
+ _Pragma ("GCC error \"Inserted possibly wrong g_error_free!\"");
+ if (error)
+ g_error_free (error);
...
}
@@
expression transfer;
identifier r;
statement S;
@@
(
- r = libusb_cancel_transfer(transfer);
- if (r < 0) S
+ _Pragma("GCC warning \"Removed libusb_cancel_transfer call!\"");
+ g_warning("USB transfer %p should be cancelled but was not due to a lack of code migration!", transfer);
|
- libusb_cancel_transfer(transfer);
+ _Pragma("GCC warning \"Removed libusb_cancel_transfer call!\"");
+ g_warning("USB transfer %p should be cancelled but was not due to a lack of code migration!", transfer);
)
# First some cleanups; some of these are required for the later stuff to work
00-misc-cleanups.cocci
01-endpoint.cocci
04-misc-renames.cocci
03-function-renames.cocci
02-type-renames.cocci
# GObject and "driver" defintion
10-driver.cocci
#
07-libusb-fill.cocci
05-libusb-1.cocci
06-libusb-callback-1.cocci
08-ssm.cocci
99-insert-checking-code.cocci
#!/bin/sh
pushd $( dirname "$0" )
all="all.cocci"
real="/tmp/real.cocci"
cat "$all" | grep -P '^(?!#).+' | xargs cat >$real || exit 1
popd
spatch --sp-file $real "$@"
This diff is collapsed.
This diff is collapsed.
/*
* fprint D-Bus daemon
* Copyright (C) 2008 Daniel Drake <dsd@gentoo.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h"
#include <glib.h>
#include <libfprint/fprint.h>
#include <poll.h>
#include <stdlib.h>
#include "loop.h"
struct fdsource {
GSource source;
GSList *pollfds;
};
static gboolean source_prepare(GSource *source, gint *timeout)
{
int r;
struct timeval tv;
r = fp_get_next_timeout(&tv);
if (r == 0) {
*timeout = -1;
return FALSE;
}
if (!timerisset(&tv))
return TRUE;
*timeout = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
return FALSE;
}
static gboolean source_check(GSource *source)
{
struct fdsource *_fdsource = (struct fdsource *) source;
GSList *l;
struct timeval tv;
int r;
if (!_fdsource->pollfds)
return FALSE;
for (l = _fdsource->pollfds; l != NULL; l = l->next) {
GPollFD *pollfd = l->data;
if (pollfd->revents)
return TRUE;
}
r = fp_get_next_timeout(&tv);
if (r == 1 && !timerisset(&tv))
return TRUE;
return FALSE;
}
static gboolean source_dispatch(GSource *source, GSourceFunc callback,
gpointer data)
{
struct timeval zerotimeout = {
.tv_sec = 0,
.tv_usec = 0,
};
/* FIXME error handling */
fp_handle_events_timeout(&zerotimeout);
/* FIXME whats the return value used for? */
return TRUE;
}
static void source_finalize(GSource *source)
{
struct fdsource *_fdsource = (struct fdsource *) source;
GSList *l;
if (!_fdsource->pollfds)
return;
for (l = _fdsource->pollfds; l != NULL; l = l->next) {
GPollFD *pollfd = l->data;
g_source_remove_poll((GSource *) _fdsource, pollfd);
g_slice_free(GPollFD, pollfd);
_fdsource->pollfds = g_slist_delete_link(_fdsource->pollfds, l);
}
g_slist_free(_fdsource->pollfds);
}
static GSourceFuncs sourcefuncs = {
.prepare = source_prepare,
.check = source_check,
.dispatch = source_dispatch,
.finalize = source_finalize,
};
static struct fdsource *fdsource = NULL;
static void pollfd_add(int fd, short events)
{
GPollFD *pollfd;
pollfd = g_slice_new(GPollFD);
pollfd->fd = fd;
pollfd->events = 0;
pollfd->revents = 0;
if (events & POLLIN)
pollfd->events |= G_IO_IN;
if (events & POLLOUT)
pollfd->events |= G_IO_OUT;
fdsource->pollfds = g_slist_prepend(fdsource->pollfds, pollfd);
g_source_add_poll((GSource *) fdsource, pollfd);
}
static void pollfd_added_cb(int fd, short events)
{
g_debug("now monitoring fd %d", fd);
pollfd_add(fd, events);
}
static void pollfd_removed_cb(int fd)
{
GSList *l;
g_debug("no longer monitoring fd %d", fd);
if (!fdsource->pollfds) {
g_debug("cannot remove from list as list is empty?");
return;
}
for (l = fdsource->pollfds; l != NULL; l = l->next) {
GPollFD *pollfd = l->data;
if (pollfd->fd != fd)
continue;
g_source_remove_poll((GSource *) fdsource, pollfd);
g_slice_free(GPollFD, pollfd);
fdsource->pollfds = g_slist_delete_link(fdsource->pollfds, l);
return;
}
g_error("couldn't find fd %d in list\n", fd);
}
int setup_pollfds(void)
{
ssize_t numfds;