@@ -604,16 +604,16 @@ def writeTOMLFile(fh, remote):
elif 'raw' in remote:
for raw in remote['raw']:
print('[[protocols.raw]]', file=fh)
- print('keycode = {}\nraw = ['.format(escapeString(raw['keycode'])), file=fh, end='')
- first = True
- for v in raw['raw']:
- if first:
- print(' {}'.format(v), file=fh, end='')
+ print('keycode = {}\nraw = \''.format(escapeString(raw['keycode'])), file=fh, end='')
+ for i, v in enumerate(raw['raw']):
+ if i == 0:
+ print('+{}'.format(v), file=fh, end='')
+ elif i % 2 == 1:
+ print(' -{}'.format(v), file=fh, end='')
else:
- print(', {}'.format(v), file=fh, end='')
- first = False
+ print(' +{}'.format(v), file=fh, end='')
- print(' ]', file=fh)
+ print('\'', file=fh)
return True
@@ -177,73 +177,113 @@ err_einval:
return EINVAL;
}
+static error_t parse_rawir_string(const char *fname, char *str, struct raw_entry **entry)
+{
+ struct raw_entry *re;
+ const char *p;
+ char *copy;
+ int i, size = 0;
+
+ // First do one scan so that we know the length
+ copy = strdup(str);
+ p = strtok(copy, "\n\t\v ,");
+ while (p) {
+ size++;
+ p = strtok(NULL, "\n\t\v ,");
+ }
+
+ re = calloc(1, sizeof(*re) + sizeof(re->raw[0]) * size);
+ if (!re) {
+ fprintf(stderr, _("Failed to allocate memory"));
+ free(copy);
+ return EINVAL;
+ }
+
+ // Second scan to extract values and validate
+ strcpy(copy, str);
+ p = strtok(copy, "\n\t\v ,");
+ i = 0;
+ while (p) {
+ long int value;
+ char *q;
+
+ value = strtoll(p, &q, 10);
+ if (*q || value == 0 || errno) {
+ fprintf(stderr, _("%s: incorrect raw value `%s'"),
+ fname, p);
+ free(copy);
+ return EINVAL;
+ }
+
+ if (value < 0) {
+ if (i % 2)
+ value = -value;
+ else {
+ fprintf(stderr, _("%s: negative raw value `%ld` at position %d only allowed for gaps/spaces"),
+ fname, value, i);
+ free(copy);
+ return EINVAL;
+ }
+ }
+
+ if (value <= 0 || value > USHRT_MAX) {
+ fprintf(stderr, _("%s: raw value %ld out of range"),
+ fname, value);
+ free(copy);
+ return EINVAL;
+ }
+
+ re->raw[i++] = value;
+
+ p = strtok(NULL, "\n\t\v ,");
+ }
+
+ free(copy);
+ re->raw_length = size;
+
+ *entry = re;
+
+ return 0;
+}
+
static error_t parse_toml_raw_part(const char *fname, struct toml_array_t *raw, struct keymap *map, bool verbose)
{
+ char *keycode, *raw_str;
struct toml_table_t *t;
- struct toml_array_t *rawarray;
struct raw_entry *re;
- const char *rkeycode;
- int ind = 0, length;
- char *keycode;
+ const char *traw;
+ int ind = 0;
while ((t = toml_table_at(raw, ind++)) != NULL) {
- rkeycode = toml_raw_in(t, "keycode");
- if (!rkeycode) {
+ traw = toml_raw_in(t, "keycode");
+ if (!traw) {
fprintf(stderr, _("%s: invalid keycode for raw entry %d\n"),
fname, ind);
return EINVAL;
}
- if (toml_rtos(rkeycode, &keycode)) {
+ if (toml_rtos(traw, &keycode)) {
fprintf(stderr, _("%s: bad value `%s' for keycode\n"),
- fname, rkeycode);
+ fname, traw);
return EINVAL;
}
- rawarray = toml_array_in(t, "raw");
- if (!rawarray) {
- fprintf(stderr, _("%s: missing raw array for entry %d\n"),
+ traw = toml_raw_in(t, "raw");
+ if (!traw) {
+ fprintf(stderr, _("%s: missing raw value for entry %d\n"),
fname, ind);
return EINVAL;
}
- // determine length of array
- length = 0;
- while (toml_raw_at(rawarray, length) != NULL)
- length++;
-
- if (!(length % 2)) {
- fprintf(stderr, _("%s: raw array must have odd length rather than %d\n"),
- fname, length);
+ if (toml_rtos(traw, &raw_str)) {
+ fprintf(stderr, _("%s: bad value `%s' for keycode\n"),
+ fname, traw);
return EINVAL;
}
- re = calloc(1, sizeof(*re) + sizeof(re->raw[0]) * length);
- if (!re) {
- fprintf(stderr, _("Failed to allocate memory"));
+ if (parse_rawir_string(fname, raw_str, &re))
return EINVAL;
- }
-
- for (int i=0; i<length; i++) {
- const char *s = toml_raw_at(rawarray, i);
- int64_t v;
-
- if (toml_rtoi(s, &v) || v == 0) {
- fprintf(stderr, _("%s: incorrect raw value `%s'"),
- fname, s);
- return EINVAL;
- }
-
- if (v <= 0 || v > USHRT_MAX) {
- fprintf(stderr, _("%s: raw value %ld out of range"),
- fname, v);
- return EINVAL;
- }
-
- re->raw[i] = v;
- }
- re->raw_length = length;
re->keycode = strdup(keycode);
re->next = map->raw;
map->raw = re;
@@ -67,10 +67,11 @@ to raw mapping. For each entry, there is a \fBkeycode\fR field and \fBraw\fR
field. The \fBkeycode\fR is a linux input event, as explained the scancodes
section.
.PP
-The \fBraw\fR field is an array of integers. These are the pulse and space
-values of the IR message. The first is a pulse value in microseconds, and
-the second a space, third pulse, etc. There should be an odd number of fields
-so that the last entry is a pulse.
+The \fBraw\fR field is an string, which lists pulse and space values,
+separated by whitespace. The first is a pulse value in microseconds, and
+the second a space, third pulse, etc. The space values can be preceded by
+a - sign and the pulse value can be preceded by a +sign.
+There should be an odd number of fields so that the last entry is a pulse.
.SS Remaining fields (BPF parameters)
If the protocol is a BPF based decoder, it may have any number of numeric
parameters. These parameters are used to support protocols with non-standard
Many programs and documentation lists raw IR a list of ints: +8800 –4400 +550 –1650 +550 –1650 +550 –1650 +550 –550 +550 The + and - are optional and are there for readability. I think this is much nicer format that 1) toml arrays and 2) lirc pulse space format. In fact, I think "ir-ctl -r" should output this format too, and support it for sending. As a first start, let's update the toml rc keymap format; the existing toml raw array has not been in a release. Signed-off-by: Sean Young <sean@mess.org> --- contrib/lircd2toml.py | 16 ++--- utils/common/keymap.c | 126 ++++++++++++++++++++++------------ utils/keytable/rc_keymap.5.in | 9 +-- 3 files changed, 96 insertions(+), 55 deletions(-)