/*
 * Power debug tool (powerdebug)
 *
 * Copyright (C) 2016, Linaro Limited.
 *
 * 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.
 *
 */

#define _GNU_SOURCE
#include <stdio.h>
#undef _GNU_SOURCE
#include <stdlib.h>

/*
 * This functions is a helper to read a specific file content and store
 * the content inside a variable pointer passed as parameter, the format
 * parameter gives the variable type to be read from the file.
 *
 * @path : directory path containing the file
 * @name : name of the file to be read
 * @format : the format of the format
 * @value : a pointer to a variable to store the content of the file
 * Returns 0 on success, -1 otherwise
 */
int file_read_value(const char *path, const char *name,
                    const char *format, void *value)
{
        FILE *file;
        char *rpath;
        int ret;

        ret = asprintf(&rpath, "%s/%s", path, name);
        if (ret < 0)
                return ret;

        file = fopen(rpath, "r");
        if (!file) {
                ret = -1;
                goto out_free;
        }

        ret = fscanf(file, format, value) == EOF ? -1 : 0;

        fclose(file);
out_free:
        free(rpath);
        return ret;
}

/*
 * This functions is a helper to write a specific file content and store
 * the content inside a variable pointer passed as parameter, the format
 * parameter gives the variable type to be write to the file.
 *
 * @path : directory path containing the file
 * @name : name of the file to be read
 * @format : the format of the format
 * @value : a pointer to a variable to store the content of the file
 * Returns 0 on success, -1 otherwise
 */
int file_write_value(const char *path, const char *name,
			const char *format, void *value)
{
	FILE *file;
	char *rpath;
	int ret;

	ret = asprintf(&rpath, "%s/%s", path, name);
	if (ret < 0)
		return ret;

	file = fopen(rpath, "w");
	if (!file) {
		ret = -1;
		goto out_free;
	}

	ret = fprintf(file, format, value) < 0 ? -1 : 0;

	fclose(file);
out_free:
	free(rpath);
	return ret;
}

int file_open(FILE **fp, const char *path, const char *name, const char *format)
{
	int ret;
	char *rpath;

	ret = asprintf(&rpath, "%s/%s", path, name);
	if (ret < 0)
		return ret;

	ret = 0;
	*fp = fopen(rpath, format);
	if (!(*fp))
		ret = -1;

	free(rpath);
	return ret;
}

int file_read_line(FILE **fp, char *line, int size)
{
	if (!(*fp))
		return -1;

	if (fgets(line, size, *fp) != NULL)
		return 0;
	else
		return -1;
}

int file_close(FILE **fp)
{
	if (!(*fp))
		return -1;

	fclose(*fp);
	return 0;
}
