tesseract/ccutil/varable.cpp
2007-03-07 20:03:40 +00:00

696 lines
23 KiB
C++

/**********************************************************************
* File: varable.c (Formerly variable.c)
* Description: Initialization and setting of VARIABLEs.
* Author: Ray Smith
* Created: Fri Feb 22 16:22:34 GMT 1991
*
* (C) Copyright 1991, Hewlett-Packard Ltd.
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
** http://www.apache.org/licenses/LICENSE-2.0
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*
**********************************************************************/
#include "mfcpch.h" //precompiled headers
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "tprintf.h"
//#include "ipeerr.h"
#include "varable.h"
#include "scanutils.h"
#define PLUS '+' //flag states
#define MINUS '-'
#define EQUAL '='
CLISTIZE (INT_VARIABLE)
CLISTIZE (BOOL_VARIABLE) CLISTIZE (STRING_VARIABLE) CLISTIZE (double_VARIABLE)
INT_VAR_FROM
INT_VARIABLE::copy;
INT_VARIABLE_CLIST
INT_VARIABLE::head; //global definition
INT_VAR_TO
INT_VARIABLE::replace;
BOOL_VAR_FROM
BOOL_VARIABLE::copy;
BOOL_VARIABLE_CLIST
BOOL_VARIABLE::head; //global definition
BOOL_VAR_TO
BOOL_VARIABLE::replace;
STRING_VAR_FROM
STRING_VARIABLE::copy;
STRING_VARIABLE_CLIST
STRING_VARIABLE::head; //global definition
STRING_VAR_TO
STRING_VARIABLE::replace;
double_VAR_FROM
double_VARIABLE::copy;
double_VARIABLE_CLIST
double_VARIABLE::head; //global definition
double_VAR_TO
double_VARIABLE::replace;
/**********************************************************************
* INT_VAR_FROM::INT_VAR_FROM
*
* Constructor to copy the list to a temporary location while the
* list head gets constructed.
**********************************************************************/
INT_VAR_FROM::INT_VAR_FROM() { //constructor
INT_VARIABLE_C_IT start_it = &INT_VARIABLE::head;
INT_VARIABLE_C_IT end_it = &INT_VARIABLE::head;
if (!start_it.empty ()) {
while (!end_it.at_last ())
end_it.forward ();
//move to copy
list.assign_to_sublist (&start_it, &end_it);
}
}
/**********************************************************************
* INT_VAR_TO::INT_VAR_TO
*
* Constructor to copy the list back to its rightful place.
**********************************************************************/
INT_VAR_TO::INT_VAR_TO() { //constructor
INT_VARIABLE_C_IT start_it = &INT_VARIABLE::copy.list;
INT_VARIABLE_C_IT end_it = &INT_VARIABLE::copy.list;
if (!start_it.empty ()) {
while (!end_it.at_last ())
end_it.forward ();
INT_VARIABLE::head.assign_to_sublist (&start_it, &end_it);
}
}
/**********************************************************************
* INT_VARIABLE::INT_VARIABLE
*
* Constructor for INT_VARIABLE. Add the variable to the static list.
**********************************************************************/
INT_VARIABLE::INT_VARIABLE( //constructor
INT32 v, //the variable
const char *vname, //of variable
const char *comment //info on variable
) {
INT_VARIABLE_C_IT it = &head; //list iterator
//tprintf("Constructing %s\n",vname);
set_value(v); //set the value
name = vname; //strings must be static
info = comment;
it.add_before_stay_put (this); //add it to stack
}
INT_VARIABLE::~INT_VARIABLE ( //constructor
) {
INT_VARIABLE_C_IT it = &head; //list iterator
for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ())
if (it.data () == this)
it.extract ();
}
/**********************************************************************
* INT_VARIABLE::get_head
*
* Get the head of the list of the variables.
**********************************************************************/
INT_VARIABLE_CLIST *INT_VARIABLE::get_head() { //access to static
return &head;
}
/**********************************************************************
* INT_VARIABLE::print
*
* Print the entire list of INT_VARIABLEs.
**********************************************************************/
void INT_VARIABLE::print( //print full list
FILE *fp //file to print on
) {
INT_VARIABLE_C_IT it = &head; //list iterator
INT_VARIABLE *elt; //current element
if (fp == stdout) {
tprintf ("#Variables of type INT_VARIABLE:\n");
for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) {
elt = it.data ();
tprintf ("%s %d #%s\n", elt->name, elt->value, elt->info);
}
}
else {
fprintf (fp, "#Variables of type INT_VARIABLE:\n");
for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) {
elt = it.data ();
fprintf (fp, "%s " INT32FORMAT " #%s\n", elt->name, elt->value,
elt->info);
}
}
}
/**********************************************************************
* BOOL_VAR_FROM::BOOL_VAR_FROM
*
* Constructor to copy the list to a temporary location while the
* list head gets constructed.
**********************************************************************/
BOOL_VAR_FROM::BOOL_VAR_FROM() { //constructor
BOOL_VARIABLE_C_IT start_it = &BOOL_VARIABLE::head;
BOOL_VARIABLE_C_IT end_it = &BOOL_VARIABLE::head;
if (!start_it.empty ()) {
while (!end_it.at_last ())
end_it.forward ();
//move to copy
list.assign_to_sublist (&start_it, &end_it);
}
}
/**********************************************************************
* BOOL_VAR_TO::BOOL_VAR_TO
*
* Constructor to copy the list back to its rightful place.
**********************************************************************/
BOOL_VAR_TO::BOOL_VAR_TO() { //constructor
BOOL_VARIABLE_C_IT start_it = &BOOL_VARIABLE::copy.list;
BOOL_VARIABLE_C_IT end_it = &BOOL_VARIABLE::copy.list;
if (!start_it.empty ()) {
while (!end_it.at_last ())
end_it.forward ();
BOOL_VARIABLE::head.assign_to_sublist (&start_it, &end_it);
}
}
/**********************************************************************
* BOOL_VARIABLE::BOOL_VARIABLE
*
* Constructor for BOOL_VARIABLE. Add the variable to the static list.
**********************************************************************/
BOOL_VARIABLE::BOOL_VARIABLE( //constructor
BOOL8 v, //the variable
const char *vname, //of variable
const char *comment //info on variable
) {
BOOL_VARIABLE_C_IT it = &head; //list iterator
//tprintf("Constructing %s\n",vname);
set_value(v); //set the value
name = vname; //strings must be static
info = comment;
it.add_before_stay_put (this); //add it to stack
}
/**********************************************************************
* BOOL_VARIABLE::BOOL_VARIABLE
*
* Constructor for BOOL_VARIABLE. Add the variable to the static list.
**********************************************************************/
BOOL_VARIABLE::~BOOL_VARIABLE () {
BOOL_VARIABLE_C_IT it = &head; //list iterator
for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ())
if (it.data () == this)
it.extract ();
}
/**********************************************************************
* BOOL_VARIABLE::get_head
*
* Get the head of the list of the variables.
**********************************************************************/
BOOL_VARIABLE_CLIST *BOOL_VARIABLE::get_head() { //access to static
return &head;
}
/**********************************************************************
* BOOL_VARIABLE::print
*
* Print the entire list of BOOL_VARIABLEs.
**********************************************************************/
void BOOL_VARIABLE::print( //print full list
FILE *fp //file to print on
) {
BOOL_VARIABLE_C_IT it = &head; //list iterator
BOOL_VARIABLE *elt; //current element
if (fp == stdout) {
tprintf ("#Variables of type BOOL_VARIABLE:\n");
for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) {
elt = it.data ();
tprintf ("%s %c #%s\n",
elt->name, elt->value ? 'T' : 'F', elt->info);
}
}
else {
fprintf (fp, "#Variables of type BOOL_VARIABLE:\n");
for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) {
elt = it.data ();
fprintf (fp, "%s %c #%s\n",
elt->name, elt->value ? 'T' : 'F', elt->info);
}
}
}
/**********************************************************************
* STRING_VAR_FROM::STRING_VAR_FROM
*
* Constructor to copy the list to a temporary location while the
* list head gets constructed.
**********************************************************************/
STRING_VAR_FROM::STRING_VAR_FROM() { //constructor
STRING_VARIABLE_C_IT start_it = &STRING_VARIABLE::head;
STRING_VARIABLE_C_IT end_it = &STRING_VARIABLE::head;
if (!start_it.empty ()) {
while (!end_it.at_last ())
end_it.forward ();
//move to copy
list.assign_to_sublist (&start_it, &end_it);
}
}
/**********************************************************************
* STRING_VAR_TO::STRING_VAR_TO
*
* Constructor to copy the list back to its rightful place.
**********************************************************************/
STRING_VAR_TO::STRING_VAR_TO() { //constructor
STRING_VARIABLE_C_IT start_it = &STRING_VARIABLE::copy.list;
STRING_VARIABLE_C_IT end_it = &STRING_VARIABLE::copy.list;
if (!start_it.empty ()) {
while (!end_it.at_last ())
end_it.forward ();
STRING_VARIABLE::head.assign_to_sublist (&start_it, &end_it);
}
}
/**********************************************************************
* STRING_VARIABLE::STRING_VARIABLE
*
* Constructor for STRING_VARIABLE. Add the variable to the static list.
**********************************************************************/
STRING_VARIABLE::STRING_VARIABLE (
//constructor
const char *v, //the variable
const char *vname, //of variable
const char *comment //info on variable
):
value(v) {
//list iterator
STRING_VARIABLE_C_IT it = &head;
//tprintf("Constructing %s\n",vname);
name = vname; //strings must be static
info = comment;
it.add_before_stay_put (this); //add it to stack
}
/**********************************************************************
* STRING_VARIABLE::~STRING_VARIABLE
*
* Destructor for STRING_VARIABLE. Add the variable to the static list.
**********************************************************************/
//constructor
STRING_VARIABLE::~STRING_VARIABLE (
) {
//list iterator
STRING_VARIABLE_C_IT it = &head;
for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ())
if (it.data () == this)
it.extract ();
}
/**********************************************************************
* STRING_VARIABLE::get_head
*
* Get the head of the list of the variables.
**********************************************************************/
STRING_VARIABLE_CLIST *STRING_VARIABLE::get_head() { //access to static
return &head;
}
/**********************************************************************
* STRING_VARIABLE::print
*
* Print the entire list of STRING_VARIABLEs.
**********************************************************************/
void STRING_VARIABLE::print( //print full list
FILE *fp //file to print on
) {
//list iterator
STRING_VARIABLE_C_IT it = &head;
STRING_VARIABLE *elt; //current element
if (fp == stdout) {
tprintf ("#Variables of type STRING_VARIABLE:\n");
for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) {
elt = it.data ();
tprintf ("%s #%s %s\n", elt->name, elt->value.string (), elt->info);
}
}
else {
fprintf (fp, "#Variables of type STRING_VARIABLE:\n");
for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) {
elt = it.data ();
fprintf (fp, "%s #%s %s\n",
elt->name, elt->value.string (), elt->info);
}
}
}
/**********************************************************************
* double_VAR_FROM::double_VAR_FROM
*
* Constructor to copy the list to a temporary location while the
* list head gets constructed.
**********************************************************************/
double_VAR_FROM::double_VAR_FROM() { //constructor
double_VARIABLE_C_IT start_it = &double_VARIABLE::head;
double_VARIABLE_C_IT end_it = &double_VARIABLE::head;
if (!start_it.empty ()) {
while (!end_it.at_last ())
end_it.forward ();
//move to copy
list.assign_to_sublist (&start_it, &end_it);
}
}
/**********************************************************************
* double_VAR_TO::double_VAR_TO
*
* Constructor to copy the list back to its rightful place.
**********************************************************************/
double_VAR_TO::double_VAR_TO() { //constructor
double_VARIABLE_C_IT start_it = &double_VARIABLE::copy.list;
double_VARIABLE_C_IT end_it = &double_VARIABLE::copy.list;
if (!start_it.empty ()) {
while (!end_it.at_last ())
end_it.forward ();
double_VARIABLE::head.assign_to_sublist (&start_it, &end_it);
}
}
/**********************************************************************
* double_VARIABLE::double_VARIABLE
*
* Constructor for double_VARIABLE. Add the variable to the static list.
**********************************************************************/
double_VARIABLE::double_VARIABLE( //constructor
double v, //the variable
const char *vname, //of variable
const char *comment //info on variable
) {
//list iterator
double_VARIABLE_C_IT it = &head;
//tprintf("Constructing %s\n",vname);
set_value(v); //set the value
name = vname; //strings must be static
info = comment;
it.add_before_stay_put (this); //add it to stack
}
double_VARIABLE::~double_VARIABLE () {
//list iterator
double_VARIABLE_C_IT it = &head;
for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ())
if (it.data () == this)
it.extract ();
}
/**********************************************************************
* double_VARIABLE::get_head
*
* Get the head of the list of the variables.
**********************************************************************/
double_VARIABLE_CLIST *double_VARIABLE::get_head() { //access to static
return &head;
}
/**********************************************************************
* double_VARIABLE::print
*
* Print the entire list of double_VARIABLEs.
**********************************************************************/
void double_VARIABLE::print( //print full list
FILE *fp //file to print on
) {
//list iterator
double_VARIABLE_C_IT it = &head;
double_VARIABLE *elt; //current element
if (fp == stdout) {
tprintf ("#Variables of type double_VARIABLE:\n");
for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) {
elt = it.data ();
tprintf ("%s %lg #%s\n", elt->name, elt->value, elt->info);
}
}
else {
fprintf (fp, "#Variables of type double_VARIABLE:\n");
for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) {
elt = it.data ();
fprintf (fp, "%s %g #%s\n", elt->name, elt->value, elt->info);
}
}
}
/**********************************************************************
* read_variables_file
*
* Read a file of variables definitions and set/modify the values therein.
* If the filename begins with a + or -, the BOOL_VARIABLEs will be
* ORed or ANDed with any current values.
* Blank lines and lines beginning # are ignored.
* Values may have any whitespace after the name and are the rest of line.
**********************************************************************/
DLLSYM BOOL8 read_variables_file( //read the file
const char *file //name to read
) {
BOOL8 anyerr; //true if any error
char flag; //file flag
BOOL8 foundit; //found variable
INT16 length; //length of line
INT16 nameoffset; //offset for real name
char *valptr; //value field
char *stringend; //end of string value
FILE *fp; //file pointer
INT32 intval; //value from file
double doubleval; //value form file
//iterators
INT_VARIABLE_C_IT int_it = &INT_VARIABLE::head;
BOOL_VARIABLE_C_IT BOOL_it = &BOOL_VARIABLE::head;
STRING_VARIABLE_C_IT STRING_it = &STRING_VARIABLE::head;
double_VARIABLE_C_IT double_it = &double_VARIABLE::head;
char line[MAX_PATH]; //input line
anyerr = FALSE;
if (*file == PLUS) {
flag = PLUS; //file has flag
nameoffset = 1;
}
else if (*file == MINUS) {
flag = MINUS;
nameoffset = 1;
}
else {
flag = EQUAL;
nameoffset = 0;
}
fp = fopen (file + nameoffset, "r");
if (fp == NULL) {
tprintf ("read_variables_file:Can't open %s", file + nameoffset);
return TRUE; //can't open it
}
while (fgets (line, MAX_PATH, fp)) {
if (line[0] != '\n' && line[0] != '#') {
length = strlen (line);
if (line[length - 1] == '\n')
line[length - 1] = '\0'; //cut newline
for (valptr = line; *valptr && *valptr != ' ' && *valptr != '\t';
valptr++);
if (*valptr) { //found blank
*valptr = '\0'; //make name a string
do
valptr++; //find end of blanks
while (*valptr == ' ' || *valptr == '\t');
if (*valptr && *valptr != '#') {
//last char in string
stringend = valptr + strlen (valptr) - 1;
while (stringend != valptr) {
while (stringend != valptr
&& (*stringend == ' ' || *stringend == '\t'))
//cut trailing blanks
stringend--;
stringend[1] = '\0'; //terminate string
while (stringend != valptr
&& (*stringend != ' ' && *stringend != '\t'
|| stringend[1] != '#'))
stringend--; //find word start
}
}
}
foundit = FALSE;
//find name
for (STRING_it.mark_cycle_pt (); !STRING_it.cycled_list () && strcmp (line, STRING_it.data ()->name); STRING_it.forward ());
//found it
if (!STRING_it.cycled_list ()) {
foundit = TRUE; //found the varaible
if (*valptr == '\0' || *valptr == '#')
STRING_it.data ()->set_value ((char *) NULL);
//no value
else
//set its value
STRING_it.data ()->set_value (valptr);
}
if (*valptr) {
//find name
for (int_it.mark_cycle_pt (); !int_it.cycled_list () && strcmp (line, int_it.data ()->name); int_it.forward ());
//found it
if (!int_it.cycled_list ()
&& sscanf (valptr, INT32FORMAT, &intval) == 1) {
foundit = TRUE; //found the varaible
//set its value
int_it.data ()->set_value (intval);
}
//find name
for (BOOL_it.mark_cycle_pt (); !BOOL_it.cycled_list () && strcmp (line, BOOL_it.data ()->name); BOOL_it.forward ());
//found it
if (!BOOL_it.cycled_list ()) {
if (*valptr == 'T' || *valptr == 't'
|| *valptr == 'Y' || *valptr == 'y' || *valptr == '1') {
foundit = TRUE;
if (flag == MINUS)
BOOL_it.data ()->set_value (FALSE);
//set to false
else
BOOL_it.data ()->set_value (TRUE);
//set to true
}
else if (*valptr == 'F' || *valptr == 'f'
|| *valptr == 'N' || *valptr == 'n'
|| *valptr == '0') {
foundit = TRUE;
if (flag == EQUAL)
BOOL_it.data ()->set_value (FALSE);
//set to false
}
}
//find name
for (double_it.mark_cycle_pt (); !double_it.cycled_list () && strcmp (line, double_it.data ()->name); double_it.forward ());
//found it
#ifdef EMBEDDED
if (!double_it.cycled_list ()) {
doubleval = strtofloat(valptr);
#else
if (!double_it.cycled_list ()
&& sscanf (valptr, "%lf", &doubleval) == 1) {
#endif
foundit = TRUE; //found the varaible
double_it.data ()->set_value (doubleval);
//set its value
}
if (!foundit) {
anyerr = TRUE; //had an error
tprintf ("read_variables_file:variable not found: %s",
line);
}
}
else if (!foundit) {
anyerr = TRUE; //had an error
tprintf ("read_variables_file:No value for variable %s", line);
}
}
}
fclose(fp); //close file
return anyerr;
}
/**********************************************************************
* print_variables
*
* Print all variable types to the given file
**********************************************************************/
DLLSYM void print_variables( //print all vars
FILE *fp //file to print on
) {
INT_VARIABLE::print(fp); //print INTs
BOOL_VARIABLE::print(fp); //print BOOLs
STRING_VARIABLE::print(fp); //print STRINGs
double_VARIABLE::print(fp); //print doubles
}