📄 valueparser.c
字号:
/* * Copyright (c) 1999 - 2001, Artur Merke <amerke@ira.uka.de> * * This code is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * It 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 General Public License for more details. * */#include "valueparser.h"#include <iostream>#include <iomanip>#include <fstream>#include <cstdio>#include <cstdlib>#include <cstring>#include <cctype>#include <cerrno>#include <climits>using namespace std;#define _FNAME_ "\n(valueparser.C):"KeyValueTab::KeyValueTab() { cur_size= 0; max_size= 0; tab= 0;}KeyValueTab::KeyValueTab(int new_max_size) { cur_size= 0; max_size= 0; tab= 0; set_max_size(new_max_size);}KeyValueTab::~KeyValueTab() { if (!tab) return; for (int i=0; i<cur_size;i++) { if (tab[i].key) delete[] tab[i].key; if (tab[i].val) delete[] tab[i].val; } delete[] tab;}bool KeyValueTab::set_cur_size(int size) { if (size < 0) return false; if (size <= max_size) cur_size= size; else { if (size/2 > max_size) set_max_size(size+10); else set_max_size(2*size+10); cur_size= size; } return true;}bool KeyValueTab::set_key(int i, const char * value, int len) { if (i < 0 || i >= cur_size) { cerr << "\nKeyValueTab::set_key: index " << i << " not in range [0," << cur_size << ")"; return false; } if (tab[i].key) { delete[] tab[i].key; tab[i].key= 0; } if (!value || len== 0) return true; if (len < 0) len= strlen(value); tab[i].key= new char[len+1]; strncpy(tab[i].key,value,len); tab[i].key[len]= '\0'; return true;}bool KeyValueTab::set_val(int i, const char * value, int len) { if (i < 0 || i >= cur_size) { cerr << "\nKeyValueTab::set_val: index " << i << " not in range [0," << cur_size << ")"; return false; } if (tab[i].val) { delete[] tab[i].val; tab[i].val= 0; } if (!value || len == 0) return true; if (len < 0) len= strlen(value); tab[i].val= new char[len+1]; strncpy(tab[i].val,value,len); tab[i].val[len]= '\0'; return true;}bool KeyValueTab::append_val(int i, const char * value, bool sep) { if (i < 0 || i >= cur_size) { cerr << "\nKeyValueTab::append: index " << i << " not in range [0," << cur_size << ")"; return false; } int my_len = 0; int val_len = 0; if (!value) return true; val_len= strlen(value); if (tab[i].val) my_len= strlen(tab[i].val); char * dum; int size= my_len+ val_len+1; if (sep && my_len>0) size++; dum= new char[size]; if (my_len>0) { strncpy(dum,tab[i].val,my_len); if (sep) { dum[my_len]= ' '; my_len++; } } strcpy(dum+my_len,value); if (tab[i].val) delete[] tab[i].val; tab[i].val= dum; return true;}bool KeyValueTab::set_max_size(int new_max_size) { if (new_max_size<0) return false; if (new_max_size<=max_size) return true; if (cur_size > max_size) cur_size= max_size; max_size= new_max_size; if (cur_size<= 0 || tab==0) { if (tab) delete[] tab; if (0==max_size) tab= 0; else { tab= new Entry[max_size]; } } else { Entry * dum= tab; tab= new Entry[max_size]; memcpy( (void*)tab,(void*)dum, sizeof(Entry) * cur_size); delete[] dum; } return true;}ostream& operator<< (ostream& o,const KeyValueTab& t) { o << "\ncur_size= " << t.cur_size << ", max_size= " << t.max_size; for (int i= 0; i<t.cur_size; i++) o << "\n" << t.tab[i].key << "= " << t.tab[i].val; return o;}/*****************************************************************************//*****************************************************************************//*****************************************************************************//*****************************************************************************/const int ValueParser::maxLineLength=500;ostream& operator<< (ostream& o,const ValueParser& t) { o << "\n<ValueParser>"; o << t.kv_tab; o << "\n</ValueParser>"; return o;}ValueParser::ValueParser(const char * fname,const char * block) : kv_tab(50), max_key_length(0){ set_verbose(false); set_warnings(false); ifstream is(fname); if (!is) { cerr << "\nCannot open control file" << fname; exit(1); //return; } char line[maxLineLength+1]; char* act; int lineNo=0; //cerr << "\nParsing file \"" << fname << "\" with block [" << block << "] "; bool in_active_block= false; int block_size= 0; if (block) block_size= strlen(block); if (block_size == 0) // in_active_block= true; while (is) { is.getline(line,maxLineLength); lineNo++; act=line; while (isspace(*act)) act++; //strip leading whitespace // Check if comment if (*act=='#') continue; // OK, comment if (*act=='[') { // OK, recognizes [block] in_active_block= false; act++; //cout << "\n act= " << act << "\n blockdata()= " << block.data() << "\n block_size= " << block_size; if ( 0==strncmp(act, block, block_size) ) { act+= block_size; if ( ']'== *act ) in_active_block= true; } continue; } if (!in_active_block) continue; read_line(act); }}ValueParser::ValueParser(int argc, char const* const * argv, const char *prefix_str) : kv_tab(50), max_key_length(0){ set_verbose(false); set_warnings(false); int prefix_str_len= 0; bool valid_prefix= false; if (prefix_str) prefix_str_len= strlen(prefix_str); if (0 == argc) return; int idx= -1; for (int i=0; i< argc; i++) { // Free entries left? const char * option_str= argv[i]; if ( '-' == option_str[0] && int( option_str[1] ) >= 58 ) //must not begin with a ciffer if ( prefix_str_len && strncmp(option_str+1,prefix_str,prefix_str_len ) != 0 ) valid_prefix= false; else { idx++; valid_prefix= true; if (idx >= kv_tab.cur_size) kv_tab.set_cur_size(idx+1); kv_tab.set_key(idx,option_str + 1 + prefix_str_len); } else if (valid_prefix) { kv_tab.append_val(idx,option_str,true); } } //cerr << "->found " << numEntries << " entries.";}ValueParser::ValueParser(int mode, const char * line) : kv_tab(10), max_key_length(0){ set_verbose(false); set_warnings(false); read_line(line);}bool ValueParser::read_line(const char * line) { const char * act=line; while ( true ) { while( isspace(*act) ) act++; if (*act=='\0' || *act=='#') return true; // OK, comment or end if (*act== '=') { cerr << "\nValueParser: wrong entry line:" << line; return false; } const char * dum= act; while ( !isspace(*dum) && *dum!= '\0' && *dum!= '=' && *dum!= '#') dum++; if (*dum== '\0' || *dum== '#' ){ cerr << "\nValueParser: wrong entry line:" << line; return false; } kv_tab.inc_cur_size(); kv_tab.set_last_key(act,dum-act); // located keyword while ( isspace(*dum) ) dum++; if ( *dum != '=' ) { cerr << "\nValueParser: wrong entry line:" << line; return false; } dum++; while ( isspace(*dum) ) dum++; act= dum; /* search for the end of the value entry. this end is defined as the end of the last succeding string, which is not a key */ while ( *dum != '\0' && *dum != '#' && *dum != '=' ) dum++; if ( *dum == '\0' || *dum == '#') { dum--; while ( isspace(*dum) ) dum--; dum++; } else { //go back until you are before the corresponding key dum--; while ( isspace(*dum) ) dum--; if (*dum == '='){ cerr << "\nValueParser: wrong entry line:" << line; return false; } while ( ! isspace(*dum) ) dum--; while ( isspace(*dum) ) dum--; dum++; } kv_tab.set_last_val(act,dum-act); act= dum; } return true;}int ValueParser::num_of_not_accessed_entries() const { int res= 0; for (int i=0; i< kv_tab.cur_size; i++) if ( kv_tab.tab[i].access < 1) res+= 1; return res;}int ValueParser::num_of_accessed_entries() const { int res= 0; for (int i=0; i< kv_tab.cur_size; i++) if ( kv_tab.tab[i].access > 0) res+= 1; return res;}int ValueParser::show_not_accessed_entries(ostream & out) const { int res= 0; for (int i=0; i< kv_tab.cur_size; i++) if ( kv_tab.tab[i].access < 1) { out << "\n" << setw(max_key_length) << setiosflags(ios::left) << kv_tab.tab[i].key << " = " << kv_tab.tab[i].val; } return res;}int str_to_int_array(bool & warning,const char* value_str,int* value,int len) { if (!value_str) return -1; if (strlen(value_str)==0) { if (len>0) warning= true; return 0; } char* error_ptr; long tmp_long; for (int i=0; i< len; i++) { while (*value_str == ' ') value_str++; if (*value_str == '\0') { warning= true; return i; } tmp_long= strtol(value_str, &error_ptr, 10); if (*error_ptr != '\0' && *error_ptr != ' ') { warning= true; return i; } else if (ERANGE == errno || tmp_long > INT_MAX || tmp_long < INT_MIN ) { warning= true; return i; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -