/******************************************************************************* * * 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 #include #include #include #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 */