Commit fcf18f52 authored by Daniel Graziotin's avatar Daniel Graziotin

Cleanup, reformatting, better Makefile and better README

parent 90e6378a
......@@ -3,7 +3,7 @@ MAINTAINERS AND CONTRIBUTORS
Daniel Graziotin <dgraziotin AT task3 DOT cc>
Ismail Khatib <ikhatib AT gmail DOT com>
Trevor Joynson
ORIGINARY AUTHORS
-----------------
......
......@@ -54,37 +54,24 @@ all: $(OBJS)
clean:
rm -rf $(SOURCE_PATH)*.$(OBJ) $(EXE)
tests:
make install
sudo /usr/sbin/mbpfan -f -v -t
install:
make
cp $(EXE) /usr/sbin
cp -n $(CONF) /etc
@echo "-----------------------------------------------------------------------------"
@echo "An init file suitable for /lib/lsb/init-functions (Debian & Ubuntu for sure)"
@echo "is located in the main folder of the source files, called mbpfan.init.debian"
@echo "Rename it to mbpfan, give it execution permissions (chmod +x mbpfan)"
@echo "and move it to /etc/init.d"
@echo "Then, add it to the default runlevels with sudo update-rc.d mbpfan defaults"
@echo ""
@echo "Additionally, an init file suitable for /etc/rc.d/init.d/functions"
@echo "(RHEL/CentOS & Fedora) is also located at the same place, this file is called"
@echo "mbpfan.init.redhat. Also rename it to mbpfan, give it execution permissions"
@echo "and move it to /etc/init.d"
@echo "To add the script to the default runlevels, run the following as root:"
@echo "chkconfig --level 2345 mbpfan on && chkconfig --level 016 mbpfan off"
@echo "******************"
@echo "INSTALL COMPLETED"
@echo "******************"
@echo ""
@echo "A configuration file has been copied to /etc/mbpfan.conf"
@echo "See README.md file to have mbpfan automatically started at system boot."
@echo ""
@echo "Please run the tests now with the command"
@echo " sudo make tests"
@echo ""
@echo "For upstart based init systems (Ubuntu), an example upstart job has been"
@echo "provided for use in place of the LSB-style init script. To use, execute"
@echo "as root:"
@echo "cp mbpfan.upstart /etc/init/mbpfan.conf"
@echo "start mbpfan"
@echo "As a special bonus, a service file for systemd is also included. To use it,"
@echo "execute the following as root:"
@echo "cp mbpfan.service /usr/lib/systemd/system"
@echo "ln -s /usr/lib/systemd/system/mbpfan.service /etc/systemd/system/mbpfan.service"
@echo "systemctl daemon-reload"
@echo "systemctl start mbpfan.service"
@echo "To start the service automatically at boot, also execute the following:"
@echo "systemctl enable mbpfan.service"
@echo "-----------------------------------------------------------------------------"
rebuild: clean all
#rebuild is not entirely correct
......@@ -3,7 +3,6 @@ Fan-Control-Daemon
Introduction
---------------------
This is an enhanced version of [rvega's Fan-Control-Daemon](https://github.com/rvega/Fan-Control-Daemon),
which itself is an enhanced version of [Allan McRae mbpfan](http://allanmcrae.com/2010/05/simple-macbook-pro-fan-daemon/)
......@@ -15,43 +14,36 @@ This enhanced version assumes any number of processors and fans (max. 10).
* It requires root use
* It daemonizes or stays in foreground
* Verbose mode for both syslog and stdout
* Users can configure it using the file /etc/mbpfan.conf
Compile Instructions
---------------------
Compile with
make
Manually compile with
gcc -o bin/mbpfan src/mbpfan.c -lm
Run The Tests (Recommended)
---------------------------
It is recommended to run the tests before installing the program
sudo ./bin/mbpfan -t
Install Instructions
--------------------
Install with
sudo make install
It actually copies mbpfan to /usr/sbin.
It copies mbpfan to /usr/sbin and mbpfan.conf to /etc
An init file suitable for /lib/lsb/init-functions (Debian & Ubuntu fur sure)
is located in the main folder of the source files. It is called mbpfan.init.debian
Rename it to mbpfan, give it execution permissions (chmod +x mbpfan)
and move it to /etc/init.d
Then, add it to the default runlevels with sudo update-rc.d mbpfan defaults (Ubuntu example)
An init file suitable for Fedora (and probably RedHat) can be found
in the file mbpfan.init.fedora
Run The Tests (Recommended)
---------------------------
It is recommended to run the tests after installing the program
sudo ./bin/mbpfan -t
or
sudo make tests
Run Instructions
---------------------
----------------
If not installed, run with
sudo bin/mbpfan
......@@ -61,9 +53,39 @@ sudo mbpfan
If installed and using the init file, run with (Ubuntu example)
sudo service mbpfan start
Starting at boot
----------------
An init file suitable for /lib/lsb/init-functions (Debian & Ubuntu for sure)
is located in the main folder of the source files, called mbpfan.init.debian
Rename it to mbpfan, give it execution permissions (chmod +x mbpfan)
and move it to /etc/init.d
Then, add it to the default runlevels with sudo update-rc.d mbpfan defaults
Additionally, an init file suitable for /etc/rc.d/init.d/functions
(RHEL/CentOS & Fedora) is also located at the same place, this file is called
mbpfan.init.redhat. Also rename it to mbpfan, give it execution permissions
and move it to /etc/init.d
To add the script to the default runlevels, run the following as root:
chkconfig --level 2345 mbpfan on && chkconfig --level 016 mbpfan off
For upstart based init systems (Ubuntu), an example upstart job has been
provided for use in place of the LSB-style init script. To use, execute
as root:
cp mbpfan.upstart /etc/init/mbpfan.conf
start mbpfan
As a special bonus, a service file for systemd is also included. To use it,
execute the following as root:
cp mbpfan.service /usr/lib/systemd/system
ln -s /usr/lib/systemd/system/mbpfan.service /etc/systemd/system/mbpfan.service
systemctl daemon-reload
systemctl start mbpfan.service
To start the service automatically at boot, also execute the following:
systemctl enable mbpfan.service
Usage
-------
Usage: ./mbpfan OPTION(S)
-h Show the help screen
-f Run in foreground
......@@ -78,7 +100,6 @@ GNU General Public License version 3
Based On
---------------------
* http://allanmcrae.com/2010/05/simple-macbook-pro-fan-daemon/
* http://allanmcrae.com/2011/08/mbp-fan-daemon-update/
* https://launchpad.net/macfanctld
......
......@@ -34,14 +34,11 @@ int write_pid(int pid)
{
FILE *file = NULL;
file = fopen(program_pid, "w");
if(file != NULL)
{
if(file != NULL) {
fprintf(file, "%d", pid);
fclose(file);
return 1;
}
else
{
} else {
return 0;
}
}
......@@ -51,8 +48,7 @@ int read_pid()
FILE *file = NULL;
int pid = -1;
file = fopen(program_pid, "r");
if(file != NULL)
{
if(file != NULL) {
fscanf(file, "%d", &pid);
fclose(file);
return pid;
......@@ -69,8 +65,7 @@ int delete_pid()
void signal_handler(int signal)
{
switch(signal)
{
switch(signal) {
case SIGHUP:
//TODO: restart myself
syslog(LOG_WARNING, "Received SIGHUP signal.");
......@@ -105,13 +100,10 @@ void go_daemon(void (*fan_control)())
syslog(LOG_INFO, "%s starting up", program_name);
// Setup syslog logging - see SETLOGMASK(3)
if(verbose)
{
if(verbose) {
setlogmask(LOG_UPTO(LOG_DEBUG));
openlog(program_name, LOG_CONS | LOG_NDELAY | LOG_PERROR | LOG_PID, LOG_USER);
}
else
{
} else {
setlogmask(LOG_UPTO(LOG_INFO));
openlog(program_name, LOG_CONS, LOG_USER);
}
......@@ -120,16 +112,13 @@ void go_daemon(void (*fan_control)())
pid_t pid_slave;
pid_t sid_slave;
if (daemonize)
{
if (daemonize) {
pid_slave = fork();
if (pid_slave < 0)
{
if (pid_slave < 0) {
exit(EXIT_FAILURE);
}
if (pid_slave > 0)
{
if (pid_slave > 0) {
// kill the father
exit(EXIT_SUCCESS);
}
......@@ -138,13 +127,11 @@ void go_daemon(void (*fan_control)())
// new sid_slave for the child process
sid_slave = setsid();
if (sid_slave < 0)
{
if (sid_slave < 0) {
exit(EXIT_FAILURE);
}
if ((chdir("/")) < 0)
{
if ((chdir("/")) < 0) {
exit(EXIT_FAILURE);
}
......@@ -159,36 +146,26 @@ void go_daemon(void (*fan_control)())
int current_pid = getpid();
if (read_pid() == -1)
{
if (verbose)
{
if (read_pid() == -1) {
if (verbose) {
printf("Writing a new .pid file with value %d at: %s\n", current_pid, program_pid);
syslog(LOG_INFO, "Writing a new .pid file with value %d at: %s", current_pid, program_pid);
}
if (write_pid(current_pid) == 0)
{
if (write_pid(current_pid) == 0) {
syslog(LOG_ERR, "Can not create a .pid file at: %s. Aborting", program_pid);
if (verbose)
{
if (verbose) {
printf("ERROR: Can not create a .pid file at: %s. Aborting\n", program_pid);
}
exit(EXIT_FAILURE);
}
else
{
if (verbose)
{
} else {
if (verbose) {
printf("Successfully written a new .pid file with value %d at: %s\n", current_pid, program_pid);
syslog(LOG_INFO, "Successfully written a new .pid file with value %d at: %s", current_pid, program_pid);
}
}
}
else
{
} else {
syslog(LOG_ERR, "A previously created .pid file exists at: %s. Aborting", program_pid);
if (verbose)
{
if (verbose) {
printf("ERROR: a previously created .pid file exists at: %s.\n Aborting\n", program_pid);
}
exit(EXIT_FAILURE);
......@@ -197,8 +174,7 @@ void go_daemon(void (*fan_control)())
fan_control();
if(daemonize)
{
if(daemonize) {
syslog(LOG_INFO, "%s daemon exiting", program_name);
}
......
......@@ -29,8 +29,7 @@ const char *program_pid = "/var/run/mbpfan.pid";
void print_usage(int argc, char *argv[])
{
if (argc >=1)
{
if (argc >=1) {
printf("Usage: %s OPTION(S) \n", argv[0]);
printf("Options:\n");
printf("\t-h Show this help screen\n");
......@@ -47,10 +46,8 @@ int main(int argc, char *argv[])
{
int c;
while( (c = getopt(argc, argv, "hftv|help")) != -1)
{
switch(c)
{
while( (c = getopt(argc, argv, "hftv|help")) != -1) {
switch(c) {
case 'h':
print_usage(argc, argv);
exit(0);
......
......@@ -58,8 +58,7 @@ int max_temp = 86; // do not set it > 90
int polling_interval = 7;
struct s_sensors
{
struct s_sensors {
char* path;
char* fan_output_path;
char* fan_manual_path;
......@@ -83,8 +82,7 @@ t_sensors *retrieve_sensors()
sprintf(number,"%d",0);
int i = 0;
for(i = 0; i<10; i++)
{
for(i = 0; i<10; i++) {
path = (char*) malloc(sizeof( char ) * path_size);
sprintf(number,"%d",i);
......@@ -95,22 +93,17 @@ t_sensors *retrieve_sensors()
FILE *file = fopen(path, "r");
if(file != NULL)
{
if(file != NULL) {
s = (t_sensors *) malloc( sizeof( t_sensors ) );
s->path = (char *) malloc(sizeof( char ) * path_size);
strcpy(s->path, path);
fscanf(file, "%d", &s->temperature);
if (sensors_head == NULL)
{
if (sensors_head == NULL) {
sensors_head = s;
sensors_head->next = NULL;
}
else
{
} else {
t_sensors *tmp = sensors_head;
while (tmp->next != NULL)
{
while (tmp->next != NULL) {
tmp = tmp->next;
}
tmp->next = s;
......@@ -145,8 +138,7 @@ void find_fans(t_sensors* sensors)
int n_sensors = 0;
int n_fans = 0;
for(n_sensors = 0; n_sensors<10; n_sensors++)
{
for(n_sensors = 0; n_sensors<10; n_sensors++) {
path_output = (char*) malloc(sizeof( char ) * path_min_size);
path_output[0] = '\0';
path_manual = (char*) malloc(sizeof( char ) * path_man_size);
......@@ -164,10 +156,8 @@ void find_fans(t_sensors* sensors)
FILE *file = fopen(path_output, "r");
if(file != NULL)
{
if (tmp->path != NULL)
{
if(file != NULL) {
if (tmp->path != NULL) {
tmp->fan_output_path = (char *) malloc(sizeof( char ) * path_min_size);
tmp->fan_manual_path = (char *) malloc(sizeof( char ) * path_man_size);
}
......@@ -179,11 +169,9 @@ void find_fans(t_sensors* sensors)
}
}
if(verbose)
{
if(verbose) {
printf("Found %d: sensors and %d fans\n", n_sensors, n_fans);
if(daemonize)
{
if(daemonize) {
syslog(LOG_INFO, "Found %d: sensors and %d fans", n_sensors, n_fans);
}
}
......@@ -199,11 +187,9 @@ void set_fans_man(t_sensors *sensors)
t_sensors *tmp = sensors;
FILE *file;
while(tmp != NULL)
{
while(tmp != NULL) {
file = fopen(tmp->fan_manual_path, "rw+");
if(file != NULL)
{
if(file != NULL) {
fprintf(file, "%d", 1);
fclose(file);
}
......@@ -216,12 +202,10 @@ t_sensors *refresh_sensors(t_sensors *sensors)
t_sensors *tmp = sensors;
while(tmp != NULL)
{
while(tmp != NULL) {
FILE *file = fopen(tmp->path, "r");
if(file != NULL)
{
if(file != NULL) {
fscanf(file, "%d", &tmp->temperature);
fclose(file);
}
......@@ -232,17 +216,14 @@ t_sensors *refresh_sensors(t_sensors *sensors)
}
/* Controls the speed of the fan */
void set_fan_speed(t_sensors* sensors, int speed)
{
t_sensors *tmp = sensors;
FILE *file;
while(tmp != NULL)
{
while(tmp != NULL) {
file = fopen(tmp->fan_output_path, "rw+");
if(file != NULL)
{
if(file != NULL) {
fprintf(file, "%d", speed);
fclose(file);
}
......@@ -253,7 +234,6 @@ void set_fan_speed(t_sensors* sensors, int speed)
}
unsigned short get_temp(t_sensors* sensors)
{
sensors = refresh_sensors(sensors);
......@@ -261,8 +241,7 @@ unsigned short get_temp(t_sensors* sensors)
unsigned short temp = 0;
t_sensors* tmp = sensors;
while(tmp != NULL)
{
while(tmp != NULL) {
sum_temp += tmp->temperature;
tmp = tmp->next;
}
......@@ -270,53 +249,33 @@ unsigned short get_temp(t_sensors* sensors)
return temp;
}
void mbpfan()
void retrieve_settings()
{
int old_temp, new_temp, fan_speed, steps;
int temp_change;
int step_up, step_down;
FILE *f = NULL;
Settings *settings = NULL;
int result = 0;
t_sensors* sensors = retrieve_sensors();
set_fans_man(sensors);
new_temp = get_temp(sensors);
fan_speed = 2000;
set_fan_speed(sensors, fan_speed);
FILE *f = NULL;
f = fopen("/etc/mbpfan.conf", "r");
if (f == NULL)
{
if (f == NULL) {
/* Could not open configfile */
if(verbose)
{
if(verbose) {
printf("Couldn't open configfile, using defaults\n");
if(daemonize)
{
if(daemonize) {
syslog(LOG_INFO, "Couldn't open configfile, using defaults");
}
}
}
else
{
} else {
settings = settings_open(f);
fclose(f);
if (settings == NULL)
{
if (settings == NULL) {
/* Could not read configfile */
if(verbose)
{
if(verbose) {
printf("Couldn't read configfile\n");
if(daemonize)
{
if(daemonize) {
syslog(LOG_INFO, "Couldn't read configfile");
}
}
}
else
{
} else {
/* Read configfile values */
result = settings_get_int(settings, "general", "min_fan_speed");
if (result != 0) min_fan_speed = result;
......@@ -335,12 +294,27 @@ void mbpfan()
settings_delete(settings);
}
}
}
void mbpfan()
{
int old_temp, new_temp, fan_speed, steps;
int temp_change;
int step_up, step_down;
retrieve_settings();
t_sensors* sensors = retrieve_sensors();
set_fans_man(sensors);
new_temp = get_temp(sensors);
fan_speed = 2000;
set_fan_speed(sensors, fan_speed);
if(verbose)
{
if(verbose) {
printf("Sleeping for %d seconds\n", polling_interval);
if(daemonize)
{
if(daemonize) {
syslog(LOG_INFO, "Sleeping for %d seconds", polling_interval);
}
}
......@@ -352,51 +326,42 @@ void mbpfan()
step_down = (float)( max_fan_speed - min_fan_speed ) /
(float)( ( max_temp - low_temp ) * ( max_temp - low_temp + 1 ) / 2 );
while(1)
{
while(1) {
old_temp = new_temp;
new_temp = get_temp(sensors);
if(new_temp >= max_temp && fan_speed != max_fan_speed)
{
if(new_temp >= max_temp && fan_speed != max_fan_speed) {
fan_speed = max_fan_speed;
}
if(new_temp <= low_temp && fan_speed != min_fan_speed)
{
if(new_temp <= low_temp && fan_speed != min_fan_speed) {
fan_speed = min_fan_speed;
}
temp_change = new_temp - old_temp;
if(temp_change > 0 && new_temp > high_temp && new_temp < max_temp)
{
if(temp_change > 0 && new_temp > high_temp && new_temp < max_temp) {
steps = ( new_temp - high_temp ) * ( new_temp - high_temp + 1 ) / 2;
fan_speed = max( fan_speed, ceil(min_fan_speed + steps * step_up) );
}
if(temp_change < 0 && new_temp > low_temp && new_temp < max_temp)
{
if(temp_change < 0 && new_temp > low_temp && new_temp < max_temp) {
steps = ( max_temp - new_temp ) * ( max_temp - new_temp + 1 ) / 2;
fan_speed = min( fan_speed, floor(max_fan_speed - steps * step_down) );
}
if(verbose)
{
if(verbose) {
printf("Old Temp %d: New Temp: %d, Fan Speed: %d\n", old_temp, new_temp, fan_speed);
if(daemonize)
{
if(daemonize) {
syslog(LOG_INFO, "Old Temp %d: New Temp: %d, Fan Speed: %d", old_temp, new_temp, fan_speed);
}
}
set_fan_speed(sensors, fan_speed);
if(verbose)
{
if(verbose) {
printf("Sleeping for %d seconds\n", polling_interval);
if(daemonize)
{
if(daemonize) {
syslog(LOG_INFO, "Sleeping for %d seconds", polling_interval);
}
}
......
......@@ -37,6 +37,13 @@ extern int polling_interval;
struct s_sensors;
typedef struct s_sensors t_sensors;
/**
* Tries to use the settings located in
* /etc/mbpfan.conf
* If it fails, the default hardcoded settings are used
*/
void retrieve_settings();
/**
* Detect the sensors in /sys/devices/platform/coretemp.0/temp
* Return a linked list of t_sensors (first temperature detected)
......
......@@ -4,13 +4,13 @@
#include <time.h>
#include <limits.h>
#include "mbpfan.h"
#include "settings.h"
#include "minunit.h"
int tests_run = 0;
struct s_sensors
{
struct s_sensors {
char* path;
char* fan_output_path;
char* fan_manual_path;
......@@ -25,8 +25,7 @@ static char *test_sensor_paths()
t_sensors* sensors = retrieve_sensors();
mu_assert("No sensors found", sensors != NULL);
t_sensors* tmp = sensors;
while(tmp != NULL)
{
while(tmp != NULL) {
mu_assert("Sensor does not have a valid path", tmp->path != NULL);
if(tmp->path != NULL)
mu_assert("Sensor does not have valid temperature", tmp->temperature > 0);
......@@ -42,8 +41,7 @@ static char *test_fan_paths()
mu_assert("No sensors found", sensors != NULL);
t_sensors* tmp = sensors;
int found_fan_path = 0;
while(tmp != NULL)
{
while(tmp != NULL) {
if(tmp->fan_output_path != NULL)
found_fan_path++;
tmp = tmp->next;
......@@ -68,10 +66,8 @@ unsigned time_seed()
int stress(int n)
{
int f = n;
while (f > 0)
{
while(n > 0)
{
while (f > 0) {
while(n > 0) {
srand ( time_seed() );
n--;
}
......@@ -92,12 +88,41 @@ static char *test_get_temp()
return 0;
}
static char *test_config_file()
{
FILE *f = NULL;
Settings *settings = NULL;
f = fopen("/etc/mbpfan.conf", "r");
mu_assert("No config file found", f != NULL);
if (f == NULL)
return 0;
settings = settings_open(f);
fclose(f);
mu_assert("Could not read settings from config file", settings != NULL);
if (settings == NULL)
return 0;
mu_assert("Could not read min_fan_speed from config file",settings_get_int(settings, "general", "min_fan_speed") != 0);
mu_assert("Could not read max_fan_speed from config file",settings_get_int(settings, "general", "max_fan_speed") != 0);
mu_assert("Could not read low_temp from config file",settings_get_int(settings, "general", "low_temp") != 0);
mu_assert("Could not read high_temp from config file",settings_get_int(settings, "general", "high_temp") != 0);
mu_assert("Could not read max_temp from config file",settings_get_int(settings, "general", "max_temp") != 0);
mu_assert("Could not read polling_interval from config file",settings_get_int(settings, "general", "polling_interval") != 0);
/* Destroy the settings object */
settings_delete(settings);
return 0;
}
static char *all_tests()
{
mu_run_test(test_sensor_paths);
mu_run_test(test_fan_paths);
mu_run_test(test_get_temp);
mu_run_test(test_config_file);
return 0;
}
......@@ -106,12 +131,9 @@ int tests()
printf("Starting the tests..\n");
printf("It is normal for them to take a bit to finish.\n");
char *result = all_tests();
if (result != 0)
{
if (result != 0) {
printf("%s \n", result);
}
else
{
} else {
printf("ALL TESTS PASSED\n");
}
printf("Tests run: %d\n", tests_run);
......
......@@ -10,6 +10,7 @@ extern int tests_run;
static char *test_sensor_paths();
static char *test_fan_paths();
static char *test_get_temp();
static char *test_config_file();
static char *all_tests();
......
......@@ -355,14 +355,11 @@ static int parse_str(Settings *settings, char *str, ParseState *parse_state)
if (*str == '\0') {
return 1;
}
else if (is_blank_str(str)) {
} else if (is_blank_str(str)) {
return 1;
}
else if (is_comment_str(str)) {
} else if (is_comment_str(str)) {
return 1;
}
else if (is_section_str(str)) {
} else if (is_section_str(str)) {
result = get_section_from_str(str, buf, sizeof(buf));
if (!result) {
return 0;
......@@ -373,8 +370,7 @@ static int parse_str(Settings *settings, char *str, ParseState *parse_state)
strcpy(parse_state->current_section, buf);
parse_state->has_section = 1;
return 1;
}
else if (is_key_value_str(str)) {
} else if (is_key_value_str(str)) {
result = get_key_value_from_str(str, buf1, sizeof(buf1), buf2, sizeof(buf2));
if (!result) {
return 0;
......@@ -383,8 +379,7 @@ static int parse_str(Settings *settings, char *str, ParseState *parse_state)
return 0;
}
return settings_set(settings, parse_state->current_section, buf1, buf2);
}
else if (is_key_without_value_str(str)) {
} else if (is_key_without_value_str(str)) {
result = get_key_without_value_from_str(str, buf, sizeof(buf));
if (!result) {
return 0;
......@@ -393,8 +388,7 @@ static int parse_str(Settings *settings, char *str, ParseState *parse_state)
return 0;
}
return settings_set(settings, parse_state->current_section, buf, "");
}
else {
} else {
return 0;
}
}
......
......@@ -43,9 +43,9 @@ extern "C"
{
#endif
typedef struct Settings Settings;
typedef struct Settings Settings;
/*
/*
* This callback function is called once per key-value when enumerating
* all keys inside a section.
*
......@@ -62,17 +62,17 @@ typedef struct Settings Settings;
*
* Return value: None.
*/
typedef void(*settings_section_enum_func)(const char *key, const char *value, const void *obj);
typedef void(*settings_section_enum_func)(const char *key, const char *value, const void *obj);
/*
/*
* Creates a settings object.
*
* Return value: A pointer to a settings object,
* or null if a new settings object could not be allocated.
*/
Settings * settings_new();
Settings * settings_new();
/*
/*
* Releases all memory held by a settings object.
*
* Parameters:
......@@ -83,9 +83,9 @@ Settings * settings_new();
*
* Return value: None.
*/
void settings_delete(Settings *settings);
void settings_delete(Settings *settings);
/*
/*
* Constructs a settings object by loading settings in textual form
* from the given stream.
*
......@@ -98,9 +98,9 @@ void settings_delete(Settings *settings);
* Return value: A pointer to a settings object,
* or null if an error occurred.
*/
Settings * settings_open(FILE *stream);
Settings * settings_open(FILE *stream);
/*
/*
* Saves the current settings object in textual form to the given stream.
*
* Parameters:
......@@ -111,9 +111,9 @@ Settings * settings_open(FILE *stream);
*
* Return value: 1 if the operation succeeded, 0 otherwise.
*/
int settings_save(const Settings *settings, FILE *stream);
int settings_save(const Settings *settings, FILE *stream);
/*
/*
* Returns the value associated with the supplied key in the
* provided section.
*
......@@ -138,9 +138,9 @@ int settings_save(const Settings *settings, FILE *stream);
* is 1 if an associated value was found and completely copied into the output buffer,
* 0 otherwise.
*/
int settings_get(const Settings *settings, const char *section, const char *key, char *out_buf, unsigned int n_out_buf);
int settings_get(const Settings *settings, const char *section, const char *key, char *out_buf, unsigned int n_out_buf);
/*
/*
* Returns the integer value associated with the supplied key in the
* provided section.
*
......@@ -157,9 +157,9 @@ int settings_get(const Settings *settings, const char *section, const char *key,
* Return value: The integer value associated to the provided section and
* key, or 0 if no such value exists.
*/
int settings_get_int(const Settings *settings, const char *section, const char *key);
int settings_get_int(const Settings *settings, const char *section, const char *key);
/*
/*
* Returns the long integer value associated with the supplied key in the
* provided section.
*
......@@ -176,9 +176,9 @@ int settings_get_int(const Settings *settings, const char *section, const char *
* Return value: The long integer value associated to the provided section and
* key, or 0 if no such value exists.
*/
long settings_get_long(const Settings *settings, const char *section, const char *key);
long settings_get_long(const Settings *settings, const char *section, const char *key);
/*
/*
* Returns the double value associated with the supplied key in the
* provided section.
*
......@@ -195,9 +195,9 @@ long settings_get_long(const Settings *settings, const char *section, const char
* Return value: The double value associated to the provided section and
* key, or 0 if no such value exists.
*/
double settings_get_double(const Settings *settings, const char *section, const char *key);
double settings_get_double(const Settings *settings, const char *section, const char *key);
/*
/*
* Returns the integer tuple associated with the supplied key in the
* provided section.
*
......@@ -218,9 +218,9 @@ double settings_get_double(const Settings *settings, const char *section, const
* Return value: 1 if the entire tuple was copied into the output buffer,
* 0 otherwise.
*/
int settings_get_int_tuple(const Settings *settings, const char *section, const char *key, int *out, unsigned int n_out);
int settings_get_int_tuple(const Settings *settings, const char *section, const char *key, int *out, unsigned int n_out);
/*
/*
* Returns the long tuple associated with the supplied key in the
* provided section.
*
......@@ -241,9 +241,9 @@ int settings_get_int_tuple(const Settings *settings, const char *section, const
* Return value: 1 if the entire tuple was copied into the output buffer,
* 0 otherwise.
*/
long settings_get_long_tuple(const Settings *settings, const char *section, const char *key, long *out, unsigned int n_out);
long settings_get_long_tuple(const Settings *settings, const char *section, const char *key, long *out, unsigned int n_out);
/*
/*
* Returns the double tuple associated with the supplied key in the
* provided section.
*
......@@ -264,9 +264,9 @@ long settings_get_long_tuple(const Settings *settings, const char *section, cons
* Return value: 1 if the entire tuple was copied into the output buffer,
* 0 otherwise.
*/
double settings_get_double_tuple(const Settings *settings, const char *section, const char *key, double *out, unsigned int n_out);
double settings_get_double_tuple(const Settings *settings, const char *section, const char *key, double *out, unsigned int n_out);
/*
/*
* Associates a value with the supplied key in the provided section.
* If the key is already associated with a value, the previous value
* is replaced.
......@@ -289,9 +289,9 @@ double settings_get_double_tuple(const Settings *settings, const char *section,
*
* Return value: 1 if the association succeeded, 0 otherwise.
*/
int settings_set(Settings *setting, const char *section, const char *key, const char *value);
int settings_set(Settings *setting, const char *section, const char *key, const char *value);
/*
/*
* Returns the number of associations between keys and values that exist
* in the provided section.
*
......@@ -305,9 +305,9 @@ int settings_set(Settings *setting, const char *section, const char *key, const
* Return value: The number of associations between keys and values in
* the provided section.
*/
int settings_section_get_count(const Settings *settings, const char *section);
int settings_section_get_count(const Settings *settings, const char *section);
/*
/*
* Enumerates all associations between keys and values in the provided
* section.
*
......@@ -328,7 +328,7 @@ int settings_section_get_count(const Settings *settings, const char *section);
*
* Return value: 1 if enumeration completed, 0 otherwise.
*/
int settings_section_enum(const Settings *settings, const char *section, settings_section_enum_func enum_func, const void *obj);
int settings_section_enum(const Settings *settings, const char *section, settings_section_enum_func enum_func, const void *obj);
#ifdef __cplusplus
}
......
......@@ -219,8 +219,7 @@ int sm_put(StrMap *map, const char *key, const char *value)
return 0;
}
bucket->count = 1;
}
else {
} else {
/* The bucket wasn't empty but no pair existed that matches the provided
* key, so create a new key-value pair.
*/
......
......@@ -44,9 +44,9 @@ extern "C"
#include <stdlib.h>
#include <string.h>
typedef struct StrMap StrMap;
typedef struct StrMap StrMap;
/*
/*
* This callback function is called once per key-value when enumerating
* all keys associated to values.
*
......@@ -63,9 +63,9 @@ typedef struct StrMap StrMap;
*
* Return value: None.
*/
typedef void(*sm_enum_func)(const char *key, const char *value, const void *obj);
typedef void(*sm_enum_func)(const char *key, const char *value, const void *obj);
/*
/*
* Creates a string map.
*
* Parameters:
......@@ -76,9 +76,9 @@ typedef void(*sm_enum_func)(const char *key, const char *value, const void *obj)
* Return value: A pointer to a string map object,
* or null if a new string map could not be allocated.
*/
StrMap * sm_new(unsigned int capacity);
StrMap * sm_new(unsigned int capacity);
/*
/*
* Releases all memory held by a string map object.
*
* Parameters:
......@@ -89,9 +89,9 @@ StrMap * sm_new(unsigned int capacity);
*
* Return value: None.
*/
void sm_delete(StrMap *map);
void sm_delete(StrMap *map);
/*
/*
* Returns the value associated with the supplied key.
*
* Parameters:
......@@ -112,9 +112,9 @@ void sm_delete(StrMap *map);
* is 1 if an associated value was found and completely copied into the output buffer,
* 0 otherwise.
*/
int sm_get(const StrMap *map, const char *key, char *out_buf, unsigned int n_out_buf);
int sm_get(const StrMap *map, const char *key, char *out_buf, unsigned int n_out_buf);
/*
/*
* Queries the existence of a key.
*
* Parameters:
......@@ -126,9 +126,9 @@ int sm_get(const StrMap *map, const char *key, char *out_buf, unsigned int n_out
*
* Return value: 1 if the key exists, 0 otherwise.
*/
int sm_exists(const StrMap *map, const char *key);
int sm_exists(const StrMap *map, const char *key);
/*
/*
* Associates a value with the supplied key. If the key is already
* associated with a value, the previous value is replaced.
*
......@@ -146,9 +146,9 @@ int sm_exists(const StrMap *map, const char *key);
*
* Return value: 1 if the association succeeded, 0 otherwise.
*/
int sm_put(StrMap *map, const char *key, const char *value);
int sm_put(StrMap *map, const char *key, const char *value);
/*
/*
* Returns the number of associations between keys and values.
*
* Parameters:
......@@ -157,9 +157,9 @@ int sm_put(StrMap *map, const char *key, const char *value);
*
* Return value: The number of associations between keys and values.
*/
int sm_get_count(const StrMap *map);
int sm_get_count(const StrMap *map);
/*
/*
* Enumerates all associations between keys and values.
*
* Parameters:
......@@ -176,7 +176,7 @@ int sm_get_count(const StrMap *map);
*
* Return value: 1 if enumeration completed, 0 otherwise.
*/
int sm_enum(const StrMap *map, sm_enum_func enum_func, const void *obj);
int sm_enum(const StrMap *map, sm_enum_func enum_func, const void *obj);
#ifdef __cplusplus
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment