📄 scanner.c
字号:
/********************************************************************************* This file is part of the General Hidden Markov Model Library,* GHMM version 0.8_beta1, see http://ghmm.org** Filename: ghmm/ghmm/scanner.c* Authors: Frank N黚el** 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: 1650 $* from $Date: 2006-07-20 17:57:27 +0200 (Thu, 20 Jul 2006) $* last change by $Author: grunau $.********************************************************************************/#ifdef HAVE_CONFIG_H# include "../config.h"#endif#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) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -