root/mylib/trunk/rconfig/rconfig.cpp

Revision 692, 20.2 kB (checked in by tapted, 2 years ago)

Add hello world and support strings as unititialised

  • Property svn:eol-style set to native
  • Property svn:keywords set to author date id revision url Rev Revision
Line 
1/* $Id$ $URL$ */
2#include "rconfig.h"
3
4#ifdef HAVE_BOOST
5#include <boost/regex.hpp>
6#include <boost/algorithm/string/trim.hpp>
7#else
8#include "rxstring/rxstring.h"
9#endif
10
11/**\file rconfig.cpp
12 * Implementation of the Readable Configuration parser, and location of
13 * the configuration variable definitions (RConfig). This should be reusable, the
14 * parser is pretty simple -- just using a few regular expressions to match
15 * each line.
16 * \author Trent Apted <tapted@it.usyd.edu.au>
17 * $Revision$
18 * $Date$
19 */
20
21#include <fstream>
22#include <map>
23
24//#include <SDL.h>
25#include <iostream>
26#include <iomanip>
27#include <sstream>
28
29#ifndef __GCC_ABI_VERSION
30/** NDEMANGLE is defined if we can't demangle staff */
31#define NDEMANGLE
32#endif
33
34#undef NDEMANGLE
35
36#ifndef NDEMANGLE
37#include <cxxabi.h>
38#endif
39
40/** Environment variable, provided by the OS */
41#ifdef __APPLE__
42#include <crt_externs.h>
43#define environ (*_NSGetEnviron())
44#else
45extern char** environ;
46#endif
47
48namespace {
49
50#ifdef HAVE_BOOST
51    typedef boost::regex MyRegex;
52    typedef boost::smatch MyMatch;
53    typedef std::string RxString;
54    inline bool mymatch(const RxString& s, MyRegex& r, MyMatch& m) {
55        return regex_match(s, m, r);
56    }
57    inline void mytrim(RxString &s) {
58        boost::algorithm::trim(s);
59    }
60#else
61    typedef RxString::Regex MyRegex;
62    typedef RxString::match_vec_type MyMatch;
63    inline bool mymatch(const RxString& s, MyRegex& r, MyMatch& m) {
64        return s.match(r, &m);
65    }
66    inline void mytrim(RxString &s) {
67        s.trim();
68    }
69#endif
70
71}
72
73RCParser::RCParser(int aargc, char** aargv, char** eenvv) :
74    argc(aargc), argv(aargv), envv(eenvv ? eenvv : environ)
75{
76}
77
78int RCParser::getArgc() const {
79    return argc;
80}
81
82char* const * RCParser::getArgv() const {
83    return argv;
84}
85
86char* const * RCParser::getEnvv() const {
87    return envv;
88}
89
90namespace RConfig {
91
92    /** Demangle a type id name */
93    const char* demangle (const char* typeid_name) {
94#ifdef NDEMANGLE
95        return typeid_name;
96#else
97        static char buf[1024];
98        int status;
99        char *demangled = abi::__cxa_demangle(typeid_name, 0, 0, &status);
100        strncpy(buf, demangled, 1024);
101        free(demangled);
102        return buf;
103#endif
104    }
105
106/** Call demangle() after getting the typeid for a variable */
107#define DEMANGLE(_var) (demangle(typeid(_var).name()))
108
109class VarReader;
110
111namespace {
112    const bool IDEBUG = true; ///< Enable debugging
113    std::string *mrcfilename = 0; ///< Sentinel filename (default?)
114    typedef std::map<std::string, VarReader*> VARMAP; ///<Type for variable lookup table
115    VARMAP *varmap = 0; ///< Variable lookup table
116}
117
118/**
119 * A class for reading variables from a file.
120 */
121class VarReader {
122protected:
123    const std::string name; ///< Name of the variable
124public:
125    /** Create a var reader looking for things with \a nname */
126    VarReader(const std::string nname) : name (nname) {}
127    /** Read in the variable from the string encountered in the config file */
128    virtual bool readin(const RxString &val) = 0;
129    virtual bool readout(RxString &val) = 0;
130    /** Virtual destructor -- does nothing */
131    virtual ~VarReader() {}
132};
133
134/**
135 * Template class that uses RxString::converTo for reading variables
136 */
137template <class T>
138class VarReaderT : public VarReader {
139protected:
140    const char* override; ///< Message to print if/when we override \a ref
141    T &ref;               ///< Where to write the variable
142public:
143    /** Create a templatized VarReader, reading into \a rref */
144    VarReaderT (T &rref, const std::string& nname, const char* ooverride = "Overriding default");
145    virtual bool readin(const RxString &val);
146    virtual bool readout(RxString &val);
147};
148
149/**
150 * Instantiate a VarReader based on the variable type
151 */
152template <class T>
153VarReader* make_varreader(T &ref, const std::string &name) {
154    return new VarReaderT<T>(ref, name);
155}
156
157/**
158 * A VarReader for reading in collection configuration variables,
159 * defers each instance to the regular VarReader
160 */
161template <class T>
162class VarReaderV : public VarReader {
163protected:
164    std::vector<T> &ref; ///< The vector reference
165    T temp;              ///< tempory var, into which we read before pushing back
166    VarReader *vr;       ///< The reader for each element
167public:
168    /** Create a vectorized var reader for \a rref */
169    VarReaderV (std::vector<T> &rref, const std::string& nname);
170    /** Virtual destructor -- deletes \a vr */
171    virtual ~VarReaderV() {delete vr;}
172    virtual bool readin(const RxString &val);
173    virtual bool readout(RxString &val);
174};
175
176/**
177 * Instantiate a VarReaderV based on a vector value type
178 */
179template <class T>
180VarReader* make_varreaderv(std::vector<T> &ref, const std::string &name) {
181    std::string localname(name);
182    return new VarReaderV<T>(ref, localname);
183}
184
185/** Add a VarReaderT to the map of variables we want to look for */
186template <class T>
187static void addvar(const char* cname, T& var, const char* context) {
188    std::string name(cname);
189    if (IDEBUG) {
190        std::cerr.setf(std::ios_base::left, std::ios_base::adjustfield);
191        std::cerr
192            << "(cfg) " << std::setw(15) << DEMANGLE(T)
193            << ' ' << std::setw(30) << name
194            << " = " << std::setw(20) << var;
195        if (context)
196            std::cerr << " (" << context << ")";
197        std::cerr << std::endl;
198
199    }
200    varmap->insert(VARMAP::value_type(name, make_varreader(var, name)));
201}
202
203template <class T>
204static void addvar_uninitialised(const char* cname, T& var, const char* initval, const char* context) {
205    std::string name(cname);
206    if (IDEBUG) {
207        std::cerr.setf(std::ios_base::left, std::ios_base::adjustfield);
208        std::cerr
209            << "(cfg) " << std::setw(15) << DEMANGLE(T)
210            << ' ' << std::setw(30) << name
211            << " = " << std::setw(20) << initval;
212        if (context)
213            std::cerr << " (" << context << ")";
214        std::cerr << std::endl;
215
216    }
217    varmap->insert(VARMAP::value_type(name, make_varreader(var, name)));
218}
219
220/** Add a VarReaderV to the map of variables we want to look for */
221template <class T>
222static void addvecvar(const char* cname, std::vector<T>& var, const char* context) {
223    std::string name(cname);
224    if (IDEBUG) {
225        std::cerr.setf(std::ios_base::left, std::ios_base::adjustfield);
226        std::cerr
227            << "(cfg) " << std::setw(15) << DEMANGLE(T)
228            << ' ' << std::setw(30) << name
229            << " = <vector>";
230        if (context)
231            std::cerr << " (" << context << ")";
232        std::cerr << std::endl;
233    }
234    varmap->insert(VARMAP::value_type(cname, make_varreaderv(var, name)));
235}
236
237/** Insert a variable reader for \a varname into the variable lookup table,
238 * where the configuration name is identical to the variable.
239 */
240#define WILLPARSE(varname) addvar( #varname , varname, "legacy rconfig.cpp" )
241
242/** Insert a variable reader for \a varname that appears in the config
243 * file as \a match
244 */
245#define WILLPARSEN(varname, match) addvar( match , varname, "legacy rconfig.cpp" )
246
247/** Insert a vector variable reader for \a varname that appears in the
248 * config file as \a match
249 */
250#define WILLPARSEV(varname, match) addvecvar( match , varname, "legacy rconfig.cpp" )
251
252/**
253 * Initialise the variable lookup table
254 */
255int rcfile_init() {
256    varmap = new VARMAP();
257    mrcfilename = new std::string("rcfile");
258    return varmap->size();
259}
260
261/** Cleanup thunks */
262void rcfile_cleanup() {
263    if (!varmap)
264        return;
265    const VARMAP::iterator e = varmap->end();
266    for (VARMAP::iterator it = varmap->begin(); it != e ; ++it)
267        delete it->second;
268    delete varmap;
269    varmap = 0;
270    delete mrcfilename;
271    mrcfilename = 0;
272}
273
274int Init::count = 0;
275Init::Init() {
276    if (count++ == 0) {
277        rcfile_init();
278    }
279}
280Init::~Init() {
281    if (--count == 0) {
282        rcfile_cleanup();
283    }
284}
285
286void rcfile_tell(const char* name, bool &ref, const char* context) {
287    addvar(name, ref, context);
288}
289void rcfile_tell(const char* name, int &ref, const char* context) {
290    addvar(name, ref, context);
291}
292void rcfile_tell(const char* name, float &ref, const char* context) {
293    addvar(name, ref, context);
294}
295void rcfile_tell(const char* name, double &ref, const char* context) {
296    addvar(name, ref, context);
297}
298void rcfile_tell(const char* name, unsigned &ref, const char* context) {
299    addvar(name, ref, context);
300}
301void rcfile_tell(const char* name, std::string &ref, const char* context) {
302    addvar(name, ref, context);
303}
304
305void rcfile_tellstr(const char* name, std::string &ref, const char* defval, const char* context) {
306    addvar_uninitialised(name, ref, defval, context);
307}
308
309/*
310void rcfile_tell(const char* name, std::vector<bool> &ref) {
311    addvecvar(name, ref);
312}*/
313void rcfile_tell(const char* name, std::vector<int> &ref, const char* context) {
314    addvecvar(name, ref, context);
315}
316void rcfile_tell(const char* name, std::vector<float> &ref, const char* context) {
317    addvecvar(name, ref, context);
318}
319void rcfile_tell(const char* name, std::vector<double> &ref, const char* context) {
320    addvecvar(name, ref, context);
321}
322void rcfile_tell(const char* name, std::vector<unsigned> &ref, const char* context) {
323    addvecvar(name, ref, context);
324}
325void rcfile_tell(const char* name, std::vector<std::string> &ref, const char* context) {
326    addvecvar(name, ref, context);
327}
328
329/** Suck out a quoted string from \a str */
330static RxString getquote(const RxString &str) {
331    size_t i;
332    bool bs = false;
333    RxString ret;
334    for (i = 0; i < str.size() && str[i] != '"'; ++i)
335        ;
336    for (i = i + 1; i < str.size() && (bs || str[i] != '"'); ++i) {
337        if (bs)
338            ret += '\\';
339        bs = str[i] == '\\';
340        if (!bs)
341            ret += str[i];
342    }
343    return ret;
344}
345
346namespace {
347    /** Parse a single line from the RCFile */
348    bool rcfile_xparseline(const RxString& line, bool suppress_unknown = false) {
349        static MyRegex line_regex("^[[:space:]]*([A-Za-z_][A-Za-z0-9_]*)[[:space:]]*=[[:space:]]*(.*)");
350        static MyRegex comment_regex("[^#]+");
351        MyMatch matches;
352        MyMatch rhs;
353        if (mymatch(line, line_regex, matches)) {
354            RxString val = matches[2];
355            RxString key = matches[1];
356            mytrim(val);
357            if (val[0] == '"') {
358                val = getquote(val);
359            } else if (mymatch(val, comment_regex, rhs)) {
360                val = rhs[0];
361            } else {
362                return false;
363            }
364            VARMAP::iterator it = varmap->find(key.c_str());
365            if (it != varmap->end()) {
366                it->second->readin(val);
367                return true;
368            } else if (!suppress_unknown) {
369                fprintf(stderr, "Unknown CFG param: %s\n", key.c_str());
370            }
371        }
372        return false;
373    }
374}
375
376
377void rcfile_getnames(std::vector<std::string> & names) {
378    VARMAP::const_iterator it = varmap->begin();
379    const VARMAP::const_iterator end = varmap->end();
380    for (; it != end; ++it)
381        names.push_back(it->first);
382}
383
384bool rcfile_parseline(const std::string& line) {
385    return rcfile_xparseline(line);
386}
387
388bool rcfile_getvalue(std::string& val, const std::string& name) {
389    VARMAP::const_iterator it = varmap->find(name);
390    if (it != varmap->end())
391        return it->second->readout(val);
392    return false;
393}
394
395int rcfile_parse(const char* file) {
396    *mrcfilename = file;
397    unsigned ctr = 0;
398    std::ifstream in(file);
399    if (in) {
400        while (in) {
401            RxString line;
402            getline(in, line);
403            if (rcfile_xparseline(line/*, varmap*/))
404                ctr++;
405        }
406    } else {
407        fprintf(stderr, "Couldn't open %s for reading\n", file);
408    }
409
410    ctr = 0;
411    if (environ) {
412        for (char** envarg = environ; *envarg; ++envarg)
413            if (rcfile_xparseline(*envarg, true))
414                ctr++;
415    }
416    return 0;
417}
418
419template <class T>
420VarReaderT<T>::VarReaderT (T &rref, const std::string& nname, const char* ooverride)
421:
422VarReader(nname), override(ooverride), ref (rref) {
423}
424
425template <class T>
426bool VarReaderT<T>::readin(const RxString &val) {
427    std::istringstream iss(val);
428    if (!(iss >> ref)) {
429        fprintf(stderr, "Bad format in %s for %s (%s)\n", mrcfilename->c_str(), name.c_str(), val.c_str());
430        return false;
431    } else {
432        fprintf(stderr, "%s %s to %s\n", override, name.c_str(), val.c_str());
433    }
434    return true;
435}
436
437template <class T>
438bool VarReaderT<T>::readout(RxString &val) {
439    std::ostringstream oss;
440    if (oss << ref) {
441        val = oss.str();
442    }
443    return oss;
444}
445
446template <>
447bool VarReaderT<std::string>::readin(const RxString &val) {
448    fprintf(stderr, "%s %s to %s\n", override, name.c_str(), val.c_str());
449    ref = val;
450    return true;
451}
452
453template <>
454bool VarReaderT<std::string>::readout(RxString &val) {
455    val = "\"";
456    val += ref;
457    val += "\"";
458    return true;
459}
460
461template <class T>
462VarReaderV<T>::VarReaderV (std::vector<T> &rref, const std::string& nname)
463:
464VarReader(nname), ref(rref), vr(new VarReaderT<T>(temp, nname + "[i]", "Adding another"))
465{
466
467}
468
469template <class T>
470bool VarReaderV<T>::readin(const RxString &val) {
471    if (vr->readin(val)) {
472        ref.push_back(temp);
473        return true;
474    }
475    return false;
476}
477
478template <class T>
479bool VarReaderV<T>::readout(RxString &val) {
480    val = "<vector>";
481    return true;
482}
483
484/**
485 * Template specialisation for strings (no formatting)
486 */
487/*
488template<>
489class VarReaderT<std::string> : public VarReader {
490protected:
491    const char* override;
492    std::string &ref;
493public:
494    VarReaderT (std::string &rref, const std::string& nname, const char* ooverride = "Overriding default")
495        :
496    VarReader(nname), override(ooverride), ref(rref) {}
497    virtual bool readin(const RxString &val) {
498        fprintf(stderr, "%s %s to %s\n", override, name.c_str(), val.c_str());
499        ref = val;
500        return true;
501    }
502};
503*/
504
505
506#ifdef OLDCRUD
507
508/** Parse a primitive type into \a varname */
509#define PARSE_PRIMITIVE(varname) else if (strcmp(matches[1].c_str(), #varname) == 0) { \
510    if(!val.convertTo(varname)) { \
511        fprintf(stderr, "Bad format in %s for %s (%s)\n", file, #varname, val.c_str()); \
512    } else { \
513        fprintf(stderr, "Overriding default %s to %s\n", #varname, val.c_str()); \
514    } \
515}
516
517/** Parse a string into \a varname */
518#define PARSE_STRING(varname) else if (strcmp(matches[1].c_str(), #varname) == 0) { \
519    fprintf(stderr, "Overriding default %s to %s\n", #varname, val.c_str()); \
520    varname = val; \
521}
522
523
524/** The old rcfile reader with quadratic scalability */
525static int oldrcfile_parse(const char* file) { /*FOLD00*/
526    *mrcfilename = file;
527    rcfile_init();
528    std::ifstream in(file);
529    if (!in) {
530        fprintf(stderr, "Couldn't open %s for reading\n", file);
531        return 1;
532    }
533    //in.setf(std::ios_base::boolalpha); //doesn't work...
534    while (in) {
535        RxString line;
536        RxString::match_vec_type matches;
537        line.append_line(in);
538        if (line.match("^[[:space:]]*([A-Za-z_][A-Za-z0-9_]*)[[:space:]]*=[[:space:]]*(.*)",
539                       &matches)) {
540            RxString::match_vec_type rhs;
541            RxString val;
542            matches[2].trim();
543            if (matches[2][0] == '"') {
544                val = getquote(matches[2]);
545            } else if (matches[2].match("[^#]+", &rhs)) {
546                val = rhs[0];
547            } else {
548                continue;
549            }
550            if (false) {
551            }
552            /* BEGIN: This is where you put all the variables to look for */
553            PARSE_PRIMITIVE(DEPTH_DELTA)
554            PARSE_PRIMITIVE(IMAGE_TRANSPARENCY)
555            PARSE_PRIMITIVE(CORNER_PROP)
556            PARSE_PRIMITIVE(TRY_FULLSCREEN)
557            PARSE_PRIMITIVE(DEFAULT_WRITE_DWELL)
558            PARSE_PRIMITIVE(TARGET_SCREEN_WIDTH)
559            PARSE_PRIMITIVE(TARGET_SCREEN_HEIGHT)
560            PARSE_PRIMITIVE(TARGET_SCREEN_BPP)
561            PARSE_PRIMITIVE(SCREEN_NUM_USERS)
562            PARSE_PRIMITIVE(TARGET_ANISOTROPIC)
563            PARSE_PRIMITIVE(TARGET_FSAA)
564            PARSE_PRIMITIVE(RENDER_NICEST)
565            PARSE_PRIMITIVE(COPY_SEPARATION_SQ)
566            PARSE_PRIMITIVE(DWELL_AREA_SQ)
567            PARSE_PRIMITIVE(JUMP_DISTANCE_SQ)
568            PARSE_PRIMITIVE(IGNORE_JUMPS)
569            PARSE_PRIMITIVE(MENU_DWELL_TIME)
570            PARSE_PRIMITIVE(COPY_GESTURE)
571            PARSE_PRIMITIVE(MOUSE_DEBUG)
572            PARSE_PRIMITIVE(MIN_REDRAW)
573            PARSE_PRIMITIVE(SHOW_FPS)
574            PARSE_PRIMITIVE(SHOW_EPS)
575            PARSE_PRIMITIVE(SHOW_NUMIMAGES)
576            PARSE_PRIMITIVE(SHOW_TIMESINCE)
577            PARSE_PRIMITIVE(SHOW_MEM)
578            PARSE_PRIMITIVE(SHOW_ANIM)
579            PARSE_PRIMITIVE(HIDE_CURSOR)
580            PARSE_PRIMITIVE(ANIMATIONS)
581            PARSE_PRIMITIVE(ANIMATION_LOAD_TIME)
582            PARSE_PRIMITIVE(WORMHOLE_MAX)
583            PARSE_PRIMITIVE(MIN_SCALE_FOR_DRAW)
584            PARSE_PRIMITIVE(FIELD_OF_VIEW_Y)
585            PARSE_PRIMITIVE(HARD_TEXTURE_LIMIT)
586            PARSE_PRIMITIVE(CAPTURE_FRAME)
587            PARSE_PRIMITIVE(ANOTO_FRAME)
588            PARSE_PRIMITIVE(JPEG_QUALITY)
589            PARSE_PRIMITIVE(ALWAYS_UPSCALE)
590            PARSE_PRIMITIVE(SINCELOCK_MAX)
591            PARSE_PRIMITIVE(SWANKY_BLACKHOLE)
592            PARSE_PRIMITIVE(CLEARSCREEN_BUG)
593            PARSE_PRIMITIVE(MANUAL_ASPECT)
594
595            PARSE_PRIMITIVE(DO_MOMENTUM)
596            PARSE_PRIMITIVE(DEFAULT_COEFF)
597            PARSE_PRIMITIVE(GRAVITY)
598            PARSE_PRIMITIVE(VELOCITY_WINDOW)
599            PARSE_PRIMITIVE(ESCAPE_VELOCITY)
600            PARSE_PRIMITIVE(BLACKHOLE_TRAPDIST)
601            PARSE_PRIMITIVE(BLACKHOLE_ACCEL)
602            PARSE_PRIMITIVE(FLIPPER_THRESHOLD)
603            PARSE_PRIMITIVE(TEST_FLIPPING)
604
605            PARSE_PRIMITIVE(SOCKET_ENABLED)
606            PARSE_PRIMITIVE(LISTEN_TIMEOUTMS)
607            PARSE_PRIMITIVE(IMAGE_SERVER_PORT)
608            PARSE_PRIMITIVE(COMMAND_SERVER_PORT)
609            PARSE_PRIMITIVE(DATAWALL_PORT)
610            PARSE_PRIMITIVE(MAGICMIRROR_PORT)
611            PARSE_PRIMITIVE(MAGICMIRROR_SEND)
612            PARSE_PRIMITIVE(AUDIOBOX_PORT)
613            PARSE_PRIMITIVE(ENABLE_AUDIOBOX)
614            PARSE_PRIMITIVE(LMB_ONLY)
615            PARSE_PRIMITIVE(SAVE_VIDEO)
616            PARSE_PRIMITIVE(MENU_SYSTEM)
617
618            PARSE_PRIMITIVE(MENU_RADIUS)
619            PARSE_PRIMITIVE(WRITING_WIDTH)
620            PARSE_PRIMITIVE(WRITING_PWIDTH)
621            PARSE_PRIMITIVE(STIPPLE_WRITING)
622            PARSE_PRIMITIVE(DO_WRITING)
623            PARSE_PRIMITIVE(FLIP_WIDGETS)
624
625            PARSE_PRIMITIVE(LOAD_X)
626            PARSE_PRIMITIVE(LOAD_Y)
627            PARSE_PRIMITIVE(LOAD_Z)
628            PARSE_PRIMITIVE(LOAD_STARTSCALE)
629            PARSE_PRIMITIVE(LOAD_FULLSCALE)
630            PARSE_PRIMITIVE(DATAWALL)
631            PARSE_PRIMITIVE(STEREO)
632            PARSE_PRIMITIVE(CAMERA_FACTOR)
633            PARSE_PRIMITIVE(DATAWALL_SEND)
634            PARSE_PRIMITIVE(STEREO_IOD)
635            PARSE_PRIMITIVE(FUSION_DISTANCE)
636            PARSE_PRIMITIVE(AUDIO_TRACKS)
637            PARSE_PRIMITIVE(X700_SELECT_BUG)
638            PARSE_PRIMITIVE(ENVMENU_DWELLRANGE)
639            PARSE_PRIMITIVE(BH_DELETE_SPEED)
640            PARSE_PRIMITIVE(PERSONAL_SPACE_COPY)
641            PARSE_PRIMITIVE(PSCOPY_RESIST_DIST)
642            PARSE_PRIMITIVE(CIRCLE_SCALE)
643            PARSE_PRIMITIVE(CIRCLE_SEGMENTS)
644            PARSE_PRIMITIVE(AUDIO_CIRCLES)
645            PARSE_PRIMITIVE(BLACK_SCREEN)
646
647
648            /* This is how you'd do a string variable */
649            PARSE_STRING(INITIAL_IMAGE_DIRECTORY)
650            PARSE_STRING(BLACKHOLE_FILE)
651            PARSE_STRING(FRAME_FILE)
652            PARSE_STRING(ANOTOFRAME_FILE)
653            PARSE_STRING(AUDIOBOX_SERVER)
654            PARSE_STRING(DATAWALL_SERVER)
655            PARSE_STRING(MAGICMIRROR_SERVER)
656            PARSE_STRING(FRAME_SOUNDFILE)
657            PARSE_STRING(RECORD_SOUNDFILE)
658
659            /* This is how you'd do a collection variable */
660            else if (matches[1] == "FILE") {
661                INITIAL_FILES.push_back(val);
662            } else if (matches[1] == "RFB_HOST") {
663                REMOTE_FRAMEBUFFERS.push_back(val);
664            } else if (matches[1] == "RFB_PORT") {
665                int p; val.convertTo(p);
666                RFB_PORTS.push_back(p);
667            } else if (matches[1] == "RFB_PASS") {
668                RFB_PASSWORDS.push_back(val);
669            }
670            /* END: variable parsing */
671            else {
672                fprintf(stderr, "Unknown CFG param: %s\n", matches[1].c_str());
673            }
674        }
675    }
676    return 0;
677} /*FOLD00*/
678
679#endif
680
681}
Note: See TracBrowser for help on using the browser.