view ffstools/newcomp/compile-fc-batt2.c @ 980:0a4d19aab608

PL129N lock-state cosmetic: 256 KiB blocks are single sectors
author Mychaela Falconia <falcon@freecalypso.org>
date Sat, 02 Dec 2023 04:31:58 +0000
parents cae22bec3cba
children
line wrap: on
line source

/*
 * This utility compiles a table of battery thresholds for the 2020-10 version
 * of FreeCalypso battery management code from ASCII source into the binary
 * form suitable for uploading into /etc/batterytab2 on a FreeCalypso device.
 */

#include <sys/types.h>
#include <ctype.h>
#include <string.h>
#include <strings.h>
#include <stdio.h>
#include <stdlib.h>
#include "../../rvinterf/include/exitcodes.h"

#define	MIN_PERCENT_THRESH	5
#define	MAX_PERCENT_THRESH	21	/* allowing 5% steps */
#define	NB_BARS_THRESH		4

char *infname;
FILE *inf;
char linebuf[256];
int lineno;

unsigned main_array_mv[MAX_PERCENT_THRESH];
unsigned main_array_percent[MAX_PERCENT_THRESH];
unsigned main_array_count;

u_char bars_thresh_array[NB_BARS_THRESH];
unsigned expect_bars = NB_BARS_THRESH, bars_index;

process_line()
{
	char *cp;
	unsigned mv, percent, bars;
	int bars_set;

	for (cp = linebuf; isspace(*cp); cp++)
		;
	if (*cp == '\0' || *cp == '#')
		return(0);
	if (!isdigit(*cp)) {
inv:		fprintf(stderr, "%s line %d: invalid syntax\n", infname,
			lineno);
		exit(ERROR_USAGE);
	}
	mv = strtoul(cp, 0, 10);
	while (isdigit(*cp))
		cp++;
	if (!isspace(*cp))
		goto inv;
	while (isspace(*cp))
		cp++;
	if (!isdigit(*cp))
		goto inv;
	percent = strtoul(cp, 0, 10);
	while (isdigit(*cp))
		cp++;
	while (isspace(*cp))
		cp++;
	if (*cp && *cp != '#') {
		if (!isdigit(*cp))
			goto inv;
		bars = strtoul(cp, 0, 10);
		while (isdigit(*cp))
			cp++;
		while (isspace(*cp))
			cp++;
		if (*cp && *cp != '#')
			goto inv;
		bars_set = 1;
	} else
		bars_set = 0;
	if (mv > 0xFFFF) {
		fprintf(stderr, "%s line %d: the millivolt value is invalid\n",
			infname, lineno);
		exit(ERROR_USAGE);
	}
	if (percent > 100) {
		fprintf(stderr, "%s line %d: the percent value is invalid\n",
			infname, lineno);
		exit(ERROR_USAGE);
	}
	if (bars_set && (bars < 1 || bars > NB_BARS_THRESH)) {
		fprintf(stderr, "%s line %d: the bars number is invalid\n",
			infname, lineno);
		exit(ERROR_USAGE);
	}
	if (main_array_count >= MAX_PERCENT_THRESH) {
		fprintf(stderr, "%s line %d: too many table entries\n",
			infname, lineno);
		exit(ERROR_USAGE);
	}
	if (main_array_count) {
		if (mv >= main_array_mv[main_array_count-1]) {
			fprintf(stderr,
			"%s line %d: millivolt numbers must be decreasing\n",
				infname, lineno);
			exit(ERROR_USAGE);
		}
		if (percent >= main_array_percent[main_array_count-1]) {
			fprintf(stderr,
			"%s line %d: percent numbers must be decreasing\n",
				infname, lineno);
			exit(ERROR_USAGE);
		}
	}
	main_array_mv[main_array_count] = mv;
	main_array_percent[main_array_count] = percent;
	if (bars_set) {
		if (bars != expect_bars) {
			fprintf(stderr,
				"%s line %d: bars threshold out of order\n",
				infname, lineno);
			exit(1);
		}
		bars_thresh_array[bars_index++] = main_array_count;
		expect_bars--;
	}
	main_array_count++;
	return(1);
}

write_output(filename)
	char *filename;
{
	FILE *of;
	unsigned n, mv, percent;

	of = fopen(filename, "w");
	if (!of) {
		perror(filename);
		exit(ERROR_UNIX);
	}
	fwrite(bars_thresh_array, 1, NB_BARS_THRESH, of);
	for (n = 0; n < main_array_count; n++) {
		mv = main_array_mv[n];
		percent = main_array_percent[n];
		putc(mv, of);
		putc(mv >> 8, of);
		putc(percent, of);
		putc(0, of);
	}
	fclose(of);
}

main(argc, argv)
	char **argv;
{
	if (argc != 3) {
		fprintf(stderr, "usage: %s srcfile output-binfile\n", argv[0]);
		exit(ERROR_USAGE);
	}
	infname = argv[1];
	inf = fopen(infname, "r");
	if (!inf) {
		perror(infname);
		exit(ERROR_UNIX);
	}
	for (lineno = 1; fgets(linebuf, sizeof linebuf, inf); lineno++)
		process_line();
	fclose(inf);
	if (main_array_count < MIN_PERCENT_THRESH) {
		fprintf(stderr, "error: %s is too short\n", infname);
		exit(ERROR_USAGE);
	}
	if (expect_bars) {
		fprintf(stderr, "error: %s did not specify bars thresholds\n",
			infname);
		exit(ERROR_USAGE);
	}
	write_output(argv[2]);
	exit(0);
}