295 lines
6.6 KiB
C
295 lines
6.6 KiB
C
/***************************************************************************
|
|
* Copyright (C) 04/2008 by Olaf Rempel *
|
|
* razzor@kopf-tisch.de *
|
|
* *
|
|
* 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; version 2 of the License *
|
|
* *
|
|
* 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., *
|
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
|
***************************************************************************/
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
|
|
#include <glib.h>
|
|
|
|
#include "tdc_proto.h"
|
|
#include "tdc_variable.h"
|
|
|
|
void tdcvar_get_value(struct tdc_var *var, char *buf, int size, int viewmode)
|
|
{
|
|
switch ((var->flags & TDC_TYPEMASK) | ((viewmode & 0x01) << 8)) {
|
|
case TDC_UNSIGNED:
|
|
switch (var->flags & TDC_SIZEMASK) {
|
|
case 1: snprintf(buf, size, "%u", var->data_uint8);
|
|
break;
|
|
|
|
case 2: snprintf(buf, size, "%u", var->data_uint16);
|
|
break;
|
|
|
|
case 4: snprintf(buf, size, "%u", var->data_uint32);
|
|
break;
|
|
|
|
case 8: snprintf(buf, size, "%llu", var->data_uint64);
|
|
break;
|
|
|
|
default:
|
|
snprintf(buf, size, "???");
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case TDC_UNSIGNED | 0x100:
|
|
switch (var->flags & TDC_SIZEMASK) {
|
|
case 1: snprintf(buf, size, "0x%02x", var->data_uint8);
|
|
break;
|
|
|
|
case 2: snprintf(buf, size, "0x%04x", var->data_uint16);
|
|
break;
|
|
|
|
case 4: snprintf(buf, size, "0x%08x", var->data_uint32);
|
|
break;
|
|
|
|
case 8: snprintf(buf, size, "0x%16llx", var->data_uint64);
|
|
break;
|
|
|
|
default:
|
|
snprintf(buf, size, "???");
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case TDC_SIGNED:
|
|
switch (var->flags & TDC_SIZEMASK) {
|
|
case 1: snprintf(buf, size, "%d", (int8_t)var->data_uint8);
|
|
break;
|
|
|
|
case 2: snprintf(buf, size, "%d", (int16_t)var->data_uint16);
|
|
break;
|
|
|
|
case 4: snprintf(buf, size, "%d", (int32_t)var->data_uint32);
|
|
break;
|
|
|
|
case 8: snprintf(buf, size, "%lld", (int64_t)var->data_uint64);
|
|
break;
|
|
|
|
default:
|
|
snprintf(buf, size, "???");
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case TDC_SIGNED | 0x100:
|
|
switch (var->flags & TDC_SIZEMASK) {
|
|
case 1: snprintf(buf, size, "0x%02x", (int8_t)var->data_uint8);
|
|
break;
|
|
|
|
case 2: snprintf(buf, size, "0x%04x", (int16_t)var->data_uint16);
|
|
break;
|
|
|
|
case 4: snprintf(buf, size, "0x%08x", (int32_t)var->data_uint32);
|
|
break;
|
|
|
|
case 8: snprintf(buf, size, "0x%16llx", (int64_t)var->data_uint64);
|
|
break;
|
|
|
|
default:
|
|
snprintf(buf, size, "???");
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case TDC_FP:
|
|
case TDC_FP | 0x100:
|
|
switch (var->flags & TDC_SIZEMASK) {
|
|
case sizeof(float):
|
|
snprintf(buf, size, "%.8f", var->data_float);
|
|
break;
|
|
|
|
case sizeof(double):
|
|
snprintf(buf, size, "%.12f", var->data_double);
|
|
break;
|
|
|
|
default:
|
|
snprintf(buf, size, "???");
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case TDC_FIXED:
|
|
case TDC_FIXED | 0x100:
|
|
snprintf(buf, size, "???");
|
|
break;
|
|
}
|
|
}
|
|
|
|
void tdcvar_get_type(struct tdc_var *var, char *buf, int size)
|
|
{
|
|
int pos;
|
|
int width = (var->flags & TDC_SIZEMASK);
|
|
|
|
switch (var->flags & TDC_TYPEMASK) {
|
|
case TDC_UNSIGNED:
|
|
pos = snprintf(buf, size, "uint%d_t", width * 8);
|
|
break;
|
|
|
|
case TDC_SIGNED:
|
|
pos = snprintf(buf, size, "int%d_t", width * 8);
|
|
break;
|
|
|
|
case TDC_FP:
|
|
if (width == sizeof(float))
|
|
pos = snprintf(buf, size, "float");
|
|
|
|
else if (size == sizeof(double))
|
|
pos = snprintf(buf, size, "double");
|
|
|
|
else
|
|
pos = snprintf(buf, size, "fp%d_t", width * 8);
|
|
break;
|
|
|
|
case TDC_FIXED:
|
|
pos = snprintf(buf, size, "fix%d_t", width * 8);
|
|
break;
|
|
|
|
default:
|
|
pos = snprintf(buf, size, "???");
|
|
break;
|
|
}
|
|
|
|
if (var->flags & TDC_READONLY)
|
|
pos = snprintf(buf + pos, size - pos, " (ro)");
|
|
}
|
|
|
|
int tdcvar_parse_value(struct tdc_var *var, char *data)
|
|
{
|
|
struct tdc_var tmp;
|
|
|
|
int width = (var->flags & TDC_SIZEMASK);
|
|
switch (var->flags & TDC_TYPEMASK) {
|
|
case TDC_UNSIGNED:
|
|
if (strchr(data, '-') != NULL)
|
|
return -1;
|
|
|
|
errno = 0;
|
|
if (width < 8)
|
|
tmp.data_uint32 = strtoul(data, NULL, 0);
|
|
else
|
|
tmp.data_uint64 = strtoull(data, NULL, 0);
|
|
|
|
if (errno != 0) {
|
|
errno = 0;
|
|
return -1;
|
|
}
|
|
break;
|
|
|
|
case TDC_SIGNED:
|
|
errno = 0;
|
|
if (width < 8)
|
|
tmp.data_uint32 = strtol(data, NULL, 0);
|
|
else
|
|
tmp.data_uint64 = strtoll(data, NULL, 0);
|
|
|
|
if (errno != 0) {
|
|
errno = 0;
|
|
return -1;
|
|
}
|
|
break;
|
|
|
|
case TDC_FP:
|
|
errno = 0;
|
|
if (width == sizeof(float))
|
|
tmp.data_float = strtod(data, NULL);
|
|
else
|
|
tmp.data_double = strtod(data, NULL);
|
|
|
|
if (errno != 0) {
|
|
errno = 0;
|
|
return -1;
|
|
}
|
|
break;
|
|
|
|
case TDC_FIXED:
|
|
return -1;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
memcpy(&var->data, &tmp.data, width);
|
|
return 0;
|
|
}
|
|
|
|
double tdcvar_get_double(struct tdc_var *var)
|
|
{
|
|
switch (var->flags & TDC_TYPEMASK) {
|
|
case TDC_UNSIGNED:
|
|
switch (var->flags & TDC_SIZEMASK) {
|
|
case 1: return var->data_uint8;
|
|
case 2: return var->data_uint16;
|
|
case 4: return var->data_uint32;
|
|
case 8: return var->data_uint64;
|
|
}
|
|
break;
|
|
|
|
case TDC_SIGNED:
|
|
switch (var->flags & TDC_SIZEMASK) {
|
|
case 1: return (int8_t)var->data_uint8;
|
|
case 2: return (int16_t)var->data_uint16;
|
|
case 4: return (int32_t)var->data_uint32;
|
|
case 8: return (int64_t)var->data_uint64;
|
|
}
|
|
break;
|
|
case TDC_FP:
|
|
case TDC_FP | 0x100:
|
|
switch (var->flags & TDC_SIZEMASK) {
|
|
case sizeof(float):
|
|
return var->data_float;
|
|
|
|
case sizeof(double):
|
|
return var->data_double;
|
|
}
|
|
break;
|
|
}
|
|
|
|
return 0.0;
|
|
}
|
|
|
|
struct tdc_var * tdcvar_create(int id, uint32_t flags, char *name, int len)
|
|
{
|
|
struct tdc_var *var = g_malloc0(sizeof(struct tdc_var) + len + 1);
|
|
var->id = id & 0xFF;
|
|
var->flags = flags;
|
|
|
|
strncpy(var->name, name, len);
|
|
var->name[len] = '\0';
|
|
|
|
// printf("create_var(%d, 0x%x, '%s', %d)\n", var->id, var->flags, var->name, len);
|
|
return var;
|
|
}
|
|
|
|
void tdcvar_update(struct tdc_var *var, uint8_t *data, int len)
|
|
{
|
|
if ((var->flags & TDC_SIZEMASK) != len)
|
|
return;
|
|
|
|
memcpy(&var->data, data, len);
|
|
}
|
|
|
|
void tdcvar_destroy(struct tdc_var *var)
|
|
{
|
|
g_free(var);
|
|
}
|