/*******************************************************************************
*
* This file is part of the General Hidden Markov Model Library,
* GHMM version __VERSION__, see http://ghmm.org
*
* Filename: ghmm/ghmm/scanner.c
* Authors: Frank Nübel
*
* Copyright (C) 1998-2004 Alexander Schliep
* Copyright (C) 1998-2001 ZAIK/ZPR, Universitaet zu Koeln
* Copyright (C) 2002-2004 Max-Planck-Institut fuer Molekulare Genetik,
* Berlin
*
* Contact: schliep@ghmm.org
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* This file is version $Revision: 1977 $
* from $Date: 2007-11-16 10:49:06 -0500 (Fri, 16 Nov 2007) $
* last change by $Author: grunau $.
*
*******************************************************************************/
#ifdef HAVE_CONFIG_H
# include "../config.h"
#endif
#include "ghmmconfig.h"
#ifdef GHMM_OBSOLETE
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "mprintf.h"
#include "mes.h"
#include "scanner.h"
#include "ghmm_internals.h"
#define SCANNER_TYPE_CHAR 1
#define SCANNER_TYPE_INT 2
#define SCANNER_TYPE_DOUBLE 3
#define SCANNER_TYPE_EDOUBLE 4
#define SCANNER_TYPE_STRING 5
#define SCANNER_TYPE_CSTRING 6
#define m_scanner_isdigit( c ) ( (c)>= '0' && (c) <= '9' )
#define m_scanner_isxdigit( c ) \
( m_scanner_isdigit(c) || ((c) >= 'a' && (c) <= 'f') || ((c)>='A' && (c)<= 'F') )
#define m_scanner_isalpha( c ) \
( ((c)>='a' && (c)<='z') || ((c)>='A' && (c)<='Z') )
#define m_scanner_isxalpha( c )\
(m_scanner_isalpha(c)||((c)&0x80 || (c)=='_'))
/*----------------------------------------------------------------------------*/
static int scanner_type (char *type, int *size)
{
if (!strcmp (type, "char")) {
*size = sizeof (char);
return (SCANNER_TYPE_CHAR);
}
if (!strcmp (type, "int")) {
*size = sizeof (int);
return (SCANNER_TYPE_INT);
}
if (!strcmp (type, "double")) {
*size = sizeof (double);
return (SCANNER_TYPE_DOUBLE);
}
if (!strcmp (type, "edouble")) {
*size = sizeof (double);
return (SCANNER_TYPE_EDOUBLE);
}
if (!strcmp (type, "string")) {
*size = sizeof (char *);
return (SCANNER_TYPE_STRING);
}
if (!strcmp (type, "cstring")) {
*size = sizeof (char *);
return (SCANNER_TYPE_CSTRING);
}
*size = 0;
return (0);
} /* scanner_type */
/*----------------------------------------------------------------------------*/
static int scanner_digit (int *val, scanner_t * s, int radix, int expect)
{
switch (radix) {
case 10:
if ('0' <= s->c && s->c <= '9')
*val = *val * 10 + s->c - '0';
else if (expect) {
ighmm_scanner_error (s, "decimal digit expected");
return (-1);
}
else
return (1);
break;
case 16:
if (s->c >= '0' && s->c <= '9')
*val = *val * 16 + s->c - '0';
else if ('A' <= s->c && s->c <= 'F')
*val = *val * 16 + s->c - 'A' + 10;
else if ('a' <= s->c && s->c <= 'f')
*val = *val * 16 + s->c - 'a' + 10;
else if (expect) {
ighmm_scanner_error (s, "decimal digit expected");
return (-1);
}
else
return (1);
break;
case 2:
if (s->c >= '0' && s->c <= '1')
*val = *val * 2 + s->c - '0';
else if (expect) {
ighmm_scanner_error (s, "binary digit expected");
return (-1);
}
else
return (1);
break;
case 8:
if (s->c >= '0' && s->c <= '7')
*val = *val * 8 + s->c - '0';
else if (expect) {
ighmm_scanner_error (s, "octal digit expected");
return (-1);
}
else
return (1);
break;
default:
return (1);
}
return (0);
} /* scanner_digit */
/*----------------------------------------------------------------------------*/
static int scanner_virtual_fgetc (scanner_t * s)
{
int c;
if (!s)
return (EOF);
c = fgetc (s->fp); /* Don't use the mes-functions here */
if (c == EOF)
return (c);
ungetc (c, s->fp);
return (c);
} /* scanner_virtual_fgetc */
/*----------------------------------------------------------------------------*/
static void scanner_fgetc (scanner_t * s)
{
int c;
if (!s)
return;
c = fgetc (s->fp); /* Don't use the mes-functions here */
if (c == EOF) {
s->c = 0;
s->eof = 1;
}
else
s->c = c;
} /* scanner_fgetc */
/*----------------------------------------------------------------------------*/
static int scanner_nextchar (scanner_t * s, int expect)
{
if (!s || s->err || s->eof)
return (0);
while (s->pos + 1 >= s->txtlen) {
int mes_stat = ighmm_mes_ability (0);
int err = ighmm_realloc ((void**)&(s->txt), sizeof(*(s->txt))*(s->txtlen + 256));
ighmm_mes_ability (mes_stat);
if (err) {
ighmm_scanner_error (s, "line too long");
return (-1);
}
else
s->txtlen += 256;
}
s->txt[s->pos] = s->c;
if (s->c == '\n') {
s->pos = 0;
s->line++;
}
else
s->pos++;
s->txt[s->pos] = 0;
scanner_fgetc (s);
if (s->eof && expect) {
ighmm_scanner_error (s, "unexpected end of file");
return (-1);
}
return (0);
} /* scanner_nextchar */
/*----------------------------------------------------------------------------*/
static int scanner_nextcchar (scanner_t * s)
{
if (!s || s->eof || s->err)
return (0);
if (s)
s->esc = 0;
if (scanner_nextchar (s, 1))
return (-1);
if (s->c - '\\')
return (0);
else {
int radix = 0;
int digits = 0;
int val = 0;
if (scanner_nextchar (s, 1))
return (-1);
s->esc = 1;
if ('0' <= s->c && s->c <= '7') {
radix = 8;
val = s->c - '0';
digits = 2;
}
else {
switch (s->c) {
case 'a':
s->c = '\a';
break;
case 'b':
s->c = '\b';
break;
case 'f':
s->c = '\f';
break;
case 'n':
s->c = '\n';
break;
case 'r':
s->c = '\r';
break;
case 't':
s->c = '\t';
break;
case 'v':
s->c = '\v';
break;
case '\\':
s->c = '\\';
break;
case '\'':
s->c = '\'';
break;
case '"':
s->c = '\"';
break;
case '?':
s->c = '\?';
break;
case 'd':
radix = 10;
digits = 3;
break;
case 'x':
radix = 16;
digits = 2;
break;
case '_':
radix = 2;
digits = 8;
break;
default:
return (0);
}
if (!radix)
return (0);
}
while (digits--) {
if (scanner_nextchar (s, 1))
return (-1);
if (scanner_digit (&val, s, radix, 1))
return (-1);
}
s->c = val;
}
return (0);
} /* scanner_nextcchar */
/*----------------------------------------------------------------------------*/
static int scanner_skipspace (scanner_t * s)
{
if (s->eof || s->err)
return (0);
while (!s->eof) {
if (s->c == '#') { /* skip comment */
do {
if (scanner_nextchar (s, 0))
return (-1);
} while (!s->eof && s->c - '\n');
}
/* New : C-Comment allowed */
else if (s->c == '/' && scanner_virtual_fgetc (s) == '*') {
do {
if (scanner_nextchar (s, 0))
return (-1);
} while (!s->eof && (s->c - '*' || scanner_virtual_fgetc (s) - '/'));
if (!s->eof && scanner_nextchar (s, 0))
return (-1);
if (!s->eof && scanner_nextchar (s, 0))
return (-1);
} /* FN: 22.10.97 */
else if (strchr (" \n\r\t\f\v\b\a", s->c)) {
if (scanner_nextchar (s, 0))
return (-1);
}
else
break;
}
return (0);
} /* scanner_skipspace */
/*----------------------------------------------------------------------------*/
static double scanner_get_length (scanner_t * s, double resolution)
{
double val = ighmm_scanner_get_double (s);
if (!s || s->err)
return (0);
if (s->eof) {
ighmm_scanner_error (s, "length expected");
return (0);
}
if (s->c - ';') {
if (resolution <= 0.0) {
ighmm_scanner_error (s, "resolution not set");
return (0);
}
s->resolution_used = 1;
if (ighmm_scanner_get_id (s))
return (0);
if (!strcmp (s->id, "INCH"))
val *= resolution;
else if (!strcmp (s->id, "CM"))
val *= (resolution / 2.54);
else if (!strcmp (s->id, "MM"))
val *= (resolution / 25.4);
else {
ighmm_scanner_error (s, "unknown length unit");
return (0);
}
}
return val;
} /* scanner_get_length */
/*============================================================================*/
/*============================================================================*/
/*============================================================================*/
int ighmm_scanner_free (scanner_t ** s)
{
# define CUR_PROC "ighmm_scanner_free"
mes_check_ptr (s, return (-1));
if (!*s)
return (0);
m_free ((*s)->filename);
m_free ((*s)->id);
m_free ((*s)->txt);
m_fclose ((*s)->fp);
m_free (*s);
return (0);
# undef CUR_PROC
} /* ighmm_scanner_free */
/*============================================================================*/
scanner_t *ighmm_scanner_alloc (const char *filename)
{
#define CUR_PROC "ighmm_scanner_alloc"
scanner_t *s = NULL;
mes_check_ptr (filename, return (NULL));
ARRAY_CALLOC (s, 1);
s->txtlen = 256;
s->idlen = 256;
if (!(s->fp = ighmm_mes_fopen (filename, "rt"))) {
GHMM_LOG_QUEUED(LCONVERTED);
goto STOP;
}
ARRAY_MALLOC (s->txt, s->txtlen);
ARRAY_MALLOC (s->id, s->txtlen);
ARRAY_CALLOC (s->filename, strlen (filename) + 1);
memcpy (s->filename, filename, strlen (filename) + 1);
s->line = 1;
s->pos = 0;
s->c = ' ';
s->err = 0;
/****************/
s->resolution_used = 0;
s->x_resolution = 0.0;
s->y_resolution = 0.0;
s->x_scale = 1.0;
s->y_scale = 1.0;
scanner_fgetc (s);
if (scanner_skipspace (s))
goto STOP;
return (s);
STOP: /* Label STOP from ARRAY_[CM]ALLOC */
ighmm_scanner_free (&s);
return (NULL);
#undef CUR_PROC
} /* ighmm_scanner_alloc */
/*============================================================================*/
int ighmm_scanner_error (scanner_t * s, char *message)
{
int i, j;
if (!s || s->err)
return (0);
j = s->pos;
while (!s->eof && s->c - '\n' && !scanner_nextchar (s, 0));
ighmm_mes_time ();
mes_file_win (s->txt);
mes_file_win ("\n");
for (i = 0; i < j; i++) {
if (s->txt[i] - '\t')
s->txt[i] = ' ';
}
s->txt[j] = 0;
mes_file_win (s->txt);
mes_file_win ("^\n");
if (message) {
ighmm_mes (MES_FILE_WIN, "Error in file %s, line %d : %s\n",
s->filename, s->line + 1, message);
}
else {
ighmm_mes (MES_FILE_WIN, "Syntax error in file %s, line %d\n",
s->filename, s->line + 1, message);
}
s->err = 1;
s->c = 0;
return (0);
} /* ighmm_scanner_error */
/*============================================================================*/
int ighmm_scanner_consume (scanner_t * s, char ch)
{
if (s->err)
return (0);
if (s->eof || ch - s->c) {
char txt[] = "' ' expected!";
txt[1] = ch;
ighmm_scanner_error (s, txt);
return (-1);
}
else if (scanner_nextchar (s, 0))
return (-1);
if (scanner_skipspace (s))
return (-1);
return (0);
} /* ighmm_scanner_consume */
/*============================================================================*/
/* Reads over a block, that's enclosed in '{' and '}'. Other blocks, lying within
this one will be skipped */
int ighmm_scanner_consume_block (scanner_t * s)
{
int open_brackets = 0;
if (s->err)
return (0);
ighmm_scanner_consume (s, '{');
if (s->err)
return (-1);
open_brackets++;
while (!s->eof && open_brackets) {
if (!('{' - s->c))
open_brackets++;
else if (!('}' - s->c))
open_brackets--;
if (scanner_nextchar (s, 0))
return (-1);
if (scanner_skipspace (s))
return (-1);
}
if (open_brackets) {
ighmm_scanner_error (s, "Unexpected EOF! '}'expected");
return (-1);
}
return (0);
} /* ighmm_scanner_consume_block */
/*============================================================================*/
int ighmm_scanner_get_name (scanner_t * s)
{
int pos = 0;
if (!s || s->err)
return (0);
while (m_scanner_isxalpha (s->c) || m_scanner_isdigit (s->c)) {
while (pos + 1 >= s->idlen) {
int mes_stat = ighmm_mes_ability (0);
int err = ighmm_realloc ((void**)&(s->txt), sizeof(*(s->txt))*(s->txtlen + 256));
ighmm_mes_ability (mes_stat);
if (err) {
ighmm_scanner_error (s, "identifier too long");
return (-1);
}
else
s->idlen += 256;
}
s->id[pos++] = s->c;
if (scanner_nextchar (s, 0))
return (-1);
}
if (!pos || m_scanner_isdigit (s->id[0]))
ighmm_scanner_error (s, "identifier expected");
s->id[pos] = 0;
if (scanner_skipspace (s))
return (-1);
return (0);
} /* ighmm_scanner_get_name */
/*============================================================================*/
int ighmm_scanner_get_id (scanner_t * s)
{
char *str;
if (!s || s->err)
return (0);
if (ighmm_scanner_get_name (s))
return (0);
str = s->id;
while (*str) {
if ('a' <= *str && *str <= 'z')
*str += 'A' - 'a';
str++;
}
return (0);
} /* ighmm_scanner_get_id */
/*============================================================================*/
char *ighmm_scanner_get_str (scanner_t * s, int *len, int cmode)
{
# define CUR_PROC "scanner_get_string"
int i = 0;
int maxlen = 128;
char *val = NULL;
if (!s || s->err)
return (NULL);
if (s->eof || s->c - '"') {
ighmm_scanner_error (s, "string expected");
goto STOP;
}
ARRAY_MALLOC (val, maxlen);
while (!s->eof && s->c == '"') {
if (cmode) {
if (scanner_nextcchar (s))
goto STOP;
}
else {
if (scanner_nextchar (s, 1))
goto STOP;
}
while (s->c - '"' || s->esc) {
if (s->eof || ((!s->c || s->c == '\n') && !s->esc)) {
ighmm_scanner_error (s, "String not closed");
goto STOP;
}
if (i + 1 == maxlen) {
ARRAY_REALLOC (val, maxlen + 128);
maxlen += 128;
}
if (s->c || len)
val[i++] = s->c;
if (cmode) {
if (scanner_nextcchar (s))
goto STOP;
}
else {
if (scanner_nextchar (s, 1))
goto STOP;
}
}
if (ighmm_scanner_consume (s, '"'))
goto STOP;
if (scanner_skipspace (s))
goto STOP;
}
val[i++] = 0;
ARRAY_REALLOC (val, i);
if (len)
*len = i;
return (val);
STOP: /* Label STOP from ARRAY_[CM]ALLOC */
m_free (val);
return (NULL);
# undef CUR_PROC
} /* ighmm_scanner_get_str */
/*============================================================================*/
char *ighmm_scanner_get_path (scanner_t * s)
{
#define CUR_PROC "ighmm_scanner_get_path"
char *res = scanner_get_string (s);
char *p;
# if defined(_PPC) || defined(_DOS) || defined(_WINDOWS)
if (res)
for (p = res; *p; p++)
if (*p == '/')
*p = '\\';
# else
if (res)
for (p = res; *p; p++)
if (*p == '\\')
*p = '/';
# endif
return (res);
#undef CUR_PROC
} /* ighmm_scanner_get_path */
/*============================================================================*/
int ighmm_scanner_get_int (scanner_t * s)
{
int val = 0;
int sign = 0;
if (!s || s->err)
return (0);
if (s->eof) {
ighmm_scanner_error (s, "integer expected");
return (0);
}
if (s->c == '-') {
if (scanner_nextchar (s, 1))
return (0);
sign = 1;
}
else if (s->c == '+') {
if (scanner_nextchar (s, 1))
return (0);
}
if (scanner_skipspace (s))
return (0);
if (s->c == '\'') {
if (scanner_nextcchar (s))
return (0);
val = (unsigned char) (s->c);
if (scanner_nextchar (s, 1))
return (0);
if (s->c - '\'') {
if (!s->esc) {
ighmm_scanner_error (s, " \' expected");
return (0);
}
val = (unsigned char) '\\';
}
else if (scanner_nextchar (s, 1))
return (0);
}
else if (!m_scanner_isdigit (s->c)) {
if (ighmm_scanner_get_id (s))
return (0);
if (!strcmp (s->id, "TRUE"))
return (sign ? 0 : 1);
else if (!strcmp (s->id, "FALSE"))
return (sign ? 1 : 0);
if (!strcmp (s->id, "ON"))
return (sign ? 0 : 1);
else if (!strcmp (s->id, "OFF"))
return (sign ? 1 : 0);
ighmm_scanner_error (s, "integer value expected");
return (0);
}
else {
int radix = 10;
if (s->c == '0') {
if (scanner_nextchar (s, 1))
return (0);
if (m_scanner_isdigit (s->c)) {
val = s->c - '0';
if (scanner_nextchar (s, 1))
return (0);
}
else
switch (s->c) {
case 'x':
case 'X':
radix = 16;
break;
case '_':
radix = 2;
break;
case 'o':
radix = 8;
break;
}
if (radix - 10) {
if (scanner_nextchar (s, 1))
return (0);
if (scanner_digit (&val, s, radix, 1))
return (0);
if (scanner_nextchar (s, 1))
return (0);
}
}
while (!scanner_digit (&val, s, radix, 0)) {
if (scanner_nextchar (s, 1))
return (0);
}
}
if (scanner_skipspace (s))
return (0);
return (sign ? -val : val);
# undef CUR_PROC
} /* ighmm_scanner_get_int */
/*============================================================================*/
double ighmm_scanner_get_double (scanner_t * s)
{
double val = 0;
int sign = 0;
if (!s || s->err)
return (0);
if (s->eof) {
ighmm_scanner_error (s, "real number expected");
return (0);
}
if (s->c == '-') {
if (scanner_nextchar (s, 1))
return (0);
sign = 1;
}
else if (s->c == '+' && scanner_nextchar (s, 1))
return (0);
if (scanner_skipspace (s))
return (0);
if (!m_scanner_isdigit (s->c) && s->c - '.') {
ighmm_scanner_error (s, "real number expected");
return (0);
}
while (m_scanner_isdigit (s->c)) {
val = 10 * val + (double) (s->c - '0');
if (scanner_nextchar (s, 1))
return (0);
}
if (s->c == '.') {
double factor = 1;
if (scanner_nextchar (s, 1))
return (0);
while (m_scanner_isdigit (s->c)) {
val = 10 * val + (double) (s->c - '0');
if (scanner_nextchar (s, 1))
return (0);
factor *= 10;
}
val /= factor;
}
if (scanner_skipspace (s))
return (0);
return (sign ? -val : val);
} /* ighmm_scanner_get_double */
/*============================================================================*/
double ighmm_scanner_get_edouble (scanner_t * s)
{
double val = 0;
int sign = 0;
if (!s || s->err)
return (0);
if (s->eof) {
ighmm_scanner_error (s, "real number expected");
return (0);
}
if (s->c == '-') {
if (scanner_nextchar (s, 1))
return (0);
sign = 1;
}
else if (s->c == '+' && scanner_nextchar (s, 1))
return (0);
if (scanner_skipspace (s))
return (0);
if (!m_scanner_isdigit (s->c) && s->c - '.') {
ighmm_scanner_error (s, "real number expected");
return (0);
}
while (m_scanner_isdigit (s->c)) {
val = 10 * val + (double) (s->c - '0');
if (scanner_nextchar (s, 1))
return (0);
}
if (s->c == '.') {
double factor = 1;
if (scanner_nextchar (s, 1))
return (0);
while (m_scanner_isdigit (s->c)) {
val = 10 * val + (double) (s->c - '0');
if (scanner_nextchar (s, 1))
return (0);
factor *= 10;
}
val /= factor;
}
if (s->c == 'e' || s->c == 'E') {
int i;
double eval;
double efactor = 1;
int esign = 0;
if (scanner_nextchar (s, 1))
return (0);
if (s->c == '-') {
if (scanner_nextchar (s, 1))
return (0);
esign = 1;
}
else if (s->c == '+' && scanner_nextchar (s, 1))
return (0);
eval = ighmm_scanner_get_int (s);
if (eval < 0)
return (0);
for (i = 0; i < eval; i++)
efactor *= 10;
if (esign)
val /= efactor;
else
val *= efactor;
}
if (scanner_skipspace (s))
return (0);
return (sign ? -val : val);
} /* ighmm_scanner_get_edouble */
/*============================================================================*/
void *ighmm_scanner_get_array (scanner_t * s, int *len, char *type)
{
#define CUR_PROC "ighmm_scanner_get_array"
int size = 0;
int typ = scanner_type (type, &size);
int maxlen = 16 * size;
char *val = NULL;
int i = 0;
char txt[256];
int err;
int mes_stat;
if (!s || !type || !len || s->err)
goto STOP;
if (!typ) {
ighmm_scanner_error (s, ighmm_mprintf (txt, sizeof (txt), "unknown type %s ", type));
goto STOP;
}
if (!len || !s || s->err)
goto STOP;
if (s->eof) {
ighmm_scanner_error (s,
ighmm_mprintf (txt, sizeof (txt), "%s array expected ", type));
goto STOP;
}
if (s->c == ';') {
*len = 0;
goto STOP;
}
mes_stat = ighmm_mes_ability (0);
val = ighmm_malloc (sizeof (char *) * maxlen);
err = !val;
ighmm_mes_ability (mes_stat);
if (err) {
ighmm_mprintf (txt, sizeof (txt), "Not enough memory to read %s array", type);
ighmm_scanner_error (s, txt);
goto STOP;
}
while (s->c - ';') {
/* Originally:
if( i && ighmm_scanner_consume( s, ',' ) ) goto STOP; */
/* Changed: read array without seperator now possible */
if (s->c == ',')
ighmm_scanner_consume (s, ',');
switch (typ) {
case SCANNER_TYPE_CHAR:
val[i] = ighmm_scanner_get_int (s);
break;
case SCANNER_TYPE_INT:
*(int *) (val + i) = ighmm_scanner_get_int (s);
break;
case SCANNER_TYPE_DOUBLE:
*(double *) (val + i) = ighmm_scanner_get_double (s);
break;
case SCANNER_TYPE_EDOUBLE:
*(double *) (val + i) = ighmm_scanner_get_edouble (s);
break;
case SCANNER_TYPE_STRING:
*(char **) (val + i) = scanner_get_string (s);
break;
case SCANNER_TYPE_CSTRING:
*(char **) (val + i) = scanner_get_cstring (s);
break;
default:
goto STOP;
}
i += size;
if (s->err)
goto STOP;
if (i == maxlen) {
mes_stat = ighmm_mes_ability (0);
err = ighmm_realloc ((void**)&val, sizeof (*val) * (maxlen + 16 * size));
ighmm_mes_ability (mes_stat);
if (err) {
ighmm_mprintf (txt, sizeof (txt), "Not enough memory to read %s array", type);
ighmm_scanner_error (s, txt);
goto STOP;
}
maxlen += 16 * size;
}
}
mes_stat = ighmm_mes_ability (0);
ighmm_realloc ((void**)&val, sizeof (*val) * i);/* Do'nt worry if this fails!*/
ighmm_mes_ability (mes_stat);
*len = i / size;
return (val);
STOP: /* Label STOP from ARRAY_[CM]ALLOC */
m_free (val);
if (len)
*len = 0;
return (NULL);
# undef CUR_PROC
} /* ighmm_scanner_get_array */
/*============================================================================*/
int ighmm_scanner_free_array (int *len, void ***arr)
{
# define CUR_PROC "ighmm_scanner_free_array"
mes_check_ptr (len, return (-1));
mes_check_ptr (arr, return (-1));
while ((*len)-- > 0) {
m_free ((*arr)[*len]);
}
free (*arr);
*len = 0;
return (0);
# undef CUR_PROC
} /* ighmm_scanner_free_array */
/*============================================================================*/
int ighmm_scanner_get_index (scanner_t * s, int n)
{
int index = n - 1;
if (!s || s->err)
return (0);
if (s->eof || s->c - '@') {
ighmm_scanner_error (s, "index expected");
return (0);
}
if (ighmm_scanner_consume (s, '@'))
return (0);
index = ighmm_scanner_get_int (s);
if (s->err)
return (0);
if (index >= n)
ighmm_scanner_error (s, "index too high");
if (ighmm_scanner_consume (s, ';'))
return (0);
return (index);
} /* ighmm_scanner_get_index */
/*============================================================================*/
double ighmm_scanner_get_resolution (scanner_t * s)
{
double val;
if (!s || s->err)
return (0);
val = ighmm_scanner_get_double (s);
if (s->err)
return (0);
if (ighmm_scanner_get_id (s))
return (0);
if (strcmp (s->id, "DPI")) {
ighmm_scanner_error (s, "dpi expected");
return (0);
}
return (val);
} /* ighmm_scanner_get_resolution */
/*============================================================================*/
int ighmm_scanner_get_length_x (scanner_t * s)
{
return (s->x_scale * scanner_get_length (s, s->x_resolution) + 0.5);
} /* ighmm_scanner_get_length_x */
/*============================================================================*/
int ighmm_scanner_get_length_y (scanner_t * s)
{
return (s->y_scale * scanner_get_length (s, s->y_resolution) + 0.5);
} /* ighmm_scanner_get_length_y */
#if defined( TEST )
/*============================================================================*/
int scanner_tst (void)
{
# define CUR_PROC "scanner_tst"
scanner_t *s = ighmm_scanner_alloc ("scanner.cfg");
char *char_arr = NULL;
int char_len = 0;
int *int_arr = NULL;
int int_len = 0;
double *double_arr = NULL;
int double_len = 0;
char **string_arr = NULL;
int string_len = 0;
int res = -1;
int i;
if (!s) {
GHMM_LOG_QUEUED(LCONVERTED);
goto STOP;
}
while (!s->err && !s->eof) {
if (ighmm_scanner_get_name (s))
break;
if (ighmm_scanner_consume (s, '='))
break;
else if (!strcmp (s->id, "char")) {
m_free (char_arr);
char_arr = scanner_get_char_array (s, &char_len);
}
else if (!strcmp (s->id, "int")) {
m_free (int_arr);
int_arr = scanner_get_int_array (s, &int_len);
}
else if (!strcmp (s->id, "string")) {
m_free (string_arr);
string_arr = scanner_get_cstring_array (s, &string_len);
}
else if (!strcmp (s->id, "double")) {
m_free (double_arr);
double_arr = scanner_get_double_array (s, &double_len);
}
else
ighmm_scanner_error (s, "unknown identifyer");
if (ighmm_scanner_consume (s, ';'))
break;
}
if (char_arr) {
mes_win ("\nchar:\n");
for (i = 0; i < char_len; i++)
ighmm_mes (MES_WIN, " '%c'\n", char_arr[i]);
}
if (int_arr) {
mes_win ("\nint:\n");
for (i = 0; i < int_len; i++)
ighmm_mes (MES_WIN, " %d\n", int_arr[i]);
}
if (double_arr) {
mes_win ("\ndouble:\n");
for (i = 0; i < double_len; i++)
ighmm_mes (MES_WIN, " %f\n", double_arr[i]);
}
if (string_arr) {
mes_win ("\nstring:\n");
for (i = 0; i < string_len; i++)
ighmm_mes (MES_WIN, " \"%s\"\n", string_arr[i]);
}
res = 0;
STOP:
ighmm_scanner_free (&s);
m_free (char_arr);
m_free (int_arr);
m_free (double_arr);
if (string_arr)
for (i = 0; i < string_len; i++)
m_free (string_arr[i]);
m_free (string_arr);
return (res);
# undef CUR_PROC
} /* scanner_tst */
#endif /* defined( TEST ) */
/*----------------------------------------------------------------------------*/
static int scanner_free_d_matrix (double ***matrix, long rows)
{
# define CUR_PROC "scanner_free_d_matrix"
long i;
mes_check_ptr (matrix, return (-1));
if (!*matrix)
return (0);
for (i = 0; i < rows; i++)
m_free ((*matrix)[i]);
m_free (*matrix);
return (0);
# undef CUR_PROC
} /* scanner_free_d_matrix */
/*============================================================================*/
double **ighmm_scanner_get_d_matrix (scanner_t * s, int *rows, int *cols)
{
#define CUR_PROC "ighmm_scanner_get_d_matrix"
double **matrix = NULL;
int local_cols = 0;
*rows = *cols = 0;
while (!s->eof && !s->err && s->c - '}') {
(*rows)++;
ARRAY_REALLOC (matrix, *rows);
matrix[*rows - 1] = scanner_get_double_array (s, &local_cols);
ighmm_scanner_consume (s, ';');
if (s->err)
goto STOP;
if (*rows > 1)
if (local_cols != *cols) {
ighmm_scanner_error (s, "rows of variing length in matrix");
goto STOP;
}
*cols = local_cols;
} /* while ... */
return matrix;
STOP: /* Label STOP from ARRAY_[CM]ALLOC */
scanner_free_d_matrix (&matrix, *rows);
return NULL;
#undef CUR_PROC
} /* ighmm_scanner_get_d_matrix */
#endif /* GHMM_OBSOLETE */