<commit_before>#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <hidapi.h>

#include "common.h"
#include "internal.h"

#include "../tempered.h"
#include "../tempered-internal.h"

/** Initialize the HID TEMPer types. */
bool temper_type_hid_init( char **error )
{
	if ( hid_init() != 0 )
	{
		if ( error != NULL )
		{
			*error = "Could not initialize the HID API.";
		}
		return false;
	}
	return true;
}

/** Finalize the HID TEMPer types. */
bool temper_type_hid_exit( char **error )
{
	if ( hid_exit() != 0 )
	{
		if ( error != NULL )
		{
			*error = "Error shutting down the HID API.";
		}
		return false;
	}
	return true;
}

/** Enumerate the HID TEMPer devices. */
struct tempered_device_list* temper_type_hid_enumerate( char **error )
{
	struct tempered_device_list *list = NULL, *current = NULL;
	struct hid_device_info *devs, *info;
	devs = hid_enumerate( 0, 0 );
	if ( devs == NULL )
	{
		if ( error != NULL )
		{
			*error = "No HID devices were found.";
		}
		return NULL;
	}
	for ( info = devs; info; info = info->next )
	{
		temper_type* type = temper_type_find(
			info->vendor_id, info->product_id, info->interface_number
		);
		if ( type != NULL && !type->ignored )
		{
			printf(
				"Device %04hx:%04hx if %d rel %4hx | %s | %ls %ls\n",
				info->vendor_id, info->product_id,
				info->interface_number, info->release_number,
				info->path,
				info->manufacturer_string, info->product_string
			);
			struct tempered_device_list *next = malloc(
				sizeof( struct tempered_device_list )
			);
			if ( next == NULL )
			{
				tempered_free_device_list( list );
				if ( error != NULL )
				{
					*error = "Unable to allocate memory for list.";
				}
				return NULL;
			}
			
			next->next = NULL;
			next->path = strdup( info->path );
			next->internal_data = type;
			next->type_name = type->name;
			next->vendor_id = info->vendor_id;
			next->product_id = info->product_id;
			next->interface_number = info->interface_number;
			
			if ( next->path == NULL )
			{
				free( next );
				tempered_free_device_list( list );
				if ( error != NULL )
				{
					*error = "Unable to allocate memory for path.";
				}
				return NULL;
			}
			
			if ( current == NULL )
			{
				list = next;
				current = list;
			}
			else
			{
				current->next = next;
				current = current->next;
			}
		}
	}
	hid_free_enumeration( devs );
	return list;
}

bool temper_type_hid_open( tempered_device* device )
{
	struct temper_type_hid_device_data *device_data = malloc(
		sizeof( struct temper_type_hid_device_data )
	);
	if ( device_data == NULL )
	{
		tempered_set_error(
			device, strdup( "Failed to allocate memory for the device data." )
		);
		return false;
	}
	device_data->hid_dev = hid_open_path( device->path );
	if ( device_data->hid_dev == NULL )
	{
		free( device_data );
		tempered_set_error( device, strdup( "Failed to open HID device." ) );
		return false;
	}
	device_data->data_length = 0;
	device_data->dev_info = (struct temper_type_hid_data*) device->type->data;
	device->data = device_data;
	return true;
}

void temper_type_hid_close( tempered_device* device )
{
	struct temper_type_hid_device_data *device_data =
		(struct temper_type_hid_device_data *) device->data;
	hid_close( device_data->hid_dev );
	free( device_data );
}

bool temper_type_hid_read_sensors( tempered_device* device )
{<commit_msg>Fixed a memory leak in the error paths.<commit_after>#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <hidapi.h>

#include "common.h"
#include "internal.h"

#include "../tempered.h"
#include "../tempered-internal.h"

/** Initialize the HID TEMPer types. */
bool temper_type_hid_init( char **error )
{
	if ( hid_init() != 0 )
	{
		if ( error != NULL )
		{
			*error = "Could not initialize the HID API.";
		}
		return false;
	}
	return true;
}

/** Finalize the HID TEMPer types. */
bool temper_type_hid_exit( char **error )
{
	if ( hid_exit() != 0 )
	{
		if ( error != NULL )
		{
			*error = "Error shutting down the HID API.";
		}
		return false;
	}
	return true;
}

/** Enumerate the HID TEMPer devices. */
struct tempered_device_list* temper_type_hid_enumerate( char **error )
{
	struct tempered_device_list *list = NULL, *current = NULL;
	struct hid_device_info *devs, *info;
	devs = hid_enumerate( 0, 0 );
	if ( devs == NULL )
	{
		if ( error != NULL )
		{
			*error = "No HID devices were found.";
		}
		return NULL;
	}
	for ( info = devs; info; info = info->next )
	{
		temper_type* type = temper_type_find(
			info->vendor_id, info->product_id, info->interface_number
		);
		if ( type != NULL && !type->ignored )
		{
			printf(
				"Device %04hx:%04hx if %d rel %4hx | %s | %ls %ls\n",
				info->vendor_id, info->product_id,
				info->interface_number, info->release_number,
				info->path,
				info->manufacturer_string, info->product_string
			);
			struct tempered_device_list *next = malloc(
				sizeof( struct tempered_device_list )
			);
			if ( next == NULL )
			{
				tempered_free_device_list( list );
				if ( error != NULL )
				{
					*error = "Unable to allocate memory for list.";
				}
				return NULL;
			}
			
			next->next = NULL;
			next->path = strdup( info->path );
			next->internal_data = type;
			next->type_name = type->name;
			next->vendor_id = info->vendor_id;
			next->product_id = info->product_id;
			next->interface_number = info->interface_number;
			
			if ( next->path == NULL )
			{
				free( next );
				tempered_free_device_list( list );
				if ( error != NULL )
				{
					*error = "Unable to allocate memory for path.";
				}
				return NULL;
			}
			
			if ( current == NULL )
			{
				list = next;
				current = list;
			}
			else
			{
				current->next = next;
				current = current->next;
			}
		}
	}
	hid_free_enumeration( devs );
	return list;
}

bool temper_type_hid_open( tempered_device* device )
{
	struct temper_type_hid_device_data *device_data = malloc(
		sizeof( struct temper_type_hid_device_data )
	);
	if ( device_data == NULL )
	{
		device->error = "Failed to allocate memory for the device data.";
		return false;
	}
	device_data->hid_dev = hid_open_path( device->path );
	if ( device_data->hid_dev == NULL )
	{
		free( device_data );
		device->error = "Failed to open HID device.";
		return false;
	}
	device_data->data_length = 0;
	device_data->dev_info = (struct temper_type_hid_data*) device->type->data;
	device->data = device_data;
	return true;
}

void temper_type_hid_close( tempered_device* device )
{
	struct temper_type_hid_device_data *device_data =
		(struct temper_type_hid_device_data *) device->data;
	hid_close( device_data->hid_dev );
	free( device_data );
}

bool temper_type_hid_read_sensors( tempered_device* device )
{
{'fraction_non_alphanumeric': 0.1346525814610921, 'fraction_numerical': 0.00297574765659872, 'mean_word_length': 3.2436868686868685, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 89, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5899994', 'n_tokens_mistral': 2767, 'n_tokens_neox': 2439, 'n_words': 579}