cocci: Add spatch/coccinelle patches for driver porting

This is an impartial set of transformations to help port the drivers to
the new interfaces.
This commit is contained in:
Benjamin Berg 2019-07-03 23:51:58 +02:00
parent 4640e3f5b0
commit 6ec11a2b26
13 changed files with 1356 additions and 0 deletions

View file

@ -0,0 +1,78 @@
// 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);

8
cocci/01-endpoint.cocci Normal file
View file

@ -0,0 +1,8 @@
@@
@@
- LIBUSB_ENDPOINT_IN
+ FP_USB_ENDPOINT_IN
@@
@@
- LIBUSB_ENDPOINT_OUT
+ FP_USB_ENDPOINT_OUT

View file

@ -0,0 +1,64 @@
@ 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

View file

@ -0,0 +1,80 @@
@@
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
)

View file

@ -0,0 +1,29 @@
@@
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
)

118
cocci/05-libusb-1.cocci Normal file
View file

@ -0,0 +1,118 @@
@ 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) { ... }
)
...
}

View file

@ -0,0 +1,344 @@
@ 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
...>
}

163
cocci/07-libusb-fill.cocci Normal file
View file

@ -0,0 +1,163 @@
///////////////////////////////////////////////////////////////////////////
// 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);

20
cocci/08-ssm.cocci Normal file
View file

@ -0,0 +1,20 @@
@ 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!\"");
...
}

386
cocci/10-driver.cocci Normal file
View file

@ -0,0 +1,386 @@
@ 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);

View file

@ -0,0 +1,38 @@
// 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);
)

19
cocci/all.cocci Normal file
View file

@ -0,0 +1,19 @@
# 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

9
cocci/apply-all Executable file
View file

@ -0,0 +1,9 @@
#!/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 "$@"