| /********************************************************************** |
| * 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; |
| |
| 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(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(double v, // the variable |
| const char *vname, // of variable |
| const char *comment // info on variable |
| ) { |
| // list iterator |
| double_VARIABLE_C_IT it = &head; |
| |
| 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(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(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 |
| // iterators |
| 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 = set_new_style_variable(line, valptr); |
| |
| if (!foundit) { |
| anyerr = TRUE; // had an error |
| tprintf("read_variables_file:variable not found: %s\n", |
| line); |
| } |
| } |
| } |
| fclose(fp); // close file |
| return anyerr; |
| } |
| |
| bool set_new_style_variable(const char *variable, const char* value) { |
| 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; |
| |
| bool foundit = false; |
| // find name |
| for (STRING_it.mark_cycle_pt(); |
| !STRING_it.cycled_list() && strcmp(variable, STRING_it.data()->name); |
| STRING_it.forward()); |
| if (!STRING_it.cycled_list()) { |
| foundit = true; // found the varaible |
| if (*value == '\0') |
| STRING_it.data()->set_value((char *) NULL); // No value. |
| else |
| STRING_it.data()->set_value(value); // set its value |
| } |
| |
| if (*value) { |
| // find name |
| for (int_it.mark_cycle_pt(); |
| !int_it.cycled_list() && strcmp(variable, int_it.data()->name); |
| int_it.forward()); |
| int intval; |
| if (!int_it.cycled_list() |
| && sscanf(value, INT32FORMAT, &intval) == 1) { |
| foundit = true; // found the varaible |
| int_it.data()->set_value(intval); // set its value. |
| } |
| for (BOOL_it.mark_cycle_pt(); |
| !BOOL_it.cycled_list () && strcmp(variable, BOOL_it.data()->name); |
| BOOL_it.forward()); |
| if (!BOOL_it.cycled_list()) { |
| if (*value == 'T' || *value == 't' || |
| *value == 'Y' || *value == 'y' || *value == '1') { |
| foundit = true; |
| BOOL_it.data()->set_value(TRUE); |
| } |
| else if (*value == 'F' || *value == 'f' || |
| *value == 'N' || *value == 'n' || *value == '0') { |
| foundit = true; |
| BOOL_it.data()->set_value(FALSE); |
| } |
| } |
| for (double_it.mark_cycle_pt(); |
| !double_it.cycled_list() && strcmp(variable, double_it.data ()->name); |
| double_it.forward()); |
| double doubleval; |
| #ifdef EMBEDDED |
| if (!double_it.cycled_list ()) { |
| doubleval = strtofloat(value); |
| #else |
| if (!double_it.cycled_list() |
| && sscanf(value, "%lf", &doubleval) == 1) { |
| #endif |
| foundit = true; // found the varaible |
| double_it.data()->set_value(doubleval); |
| } |
| } |
| return foundit; |
| } |
| |
| /********************************************************************** |
| * 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 |
| } |