/* * VNACFG.h. * * Greg Ordy * * Read an N2PK NA.CFG file, picking out the contents. * The data is held in a C++ class, and was developed * with the Microsoft C Compiler, version 6. * * In normal use, the first file read will be the CFG file * next to the executable. That sets various "system" values, * such as the clock frequency. Then, it is possible to read * a file in each data folder. The values replace earlier * set values. * */ #include // void debugf (char *, ...); // write printf strings to a console #define VNACFGFILENAME ("VNA.CFG") /* * General syntax: * NAME = VALUE * Comments are enclosed in parenthesis, as in: (this is a comment) * Only positive number values are allowed at this point. * Names are case insensitive. */ #define VEC_NOERROR 0 #define VEC_DONOTHING 1 /* * The data carried in the configuration file. */ class CVNACFG { /* * The important data, manipulated via get and set calls below. */ int m_Port; // VNA parallel port address (0x378, for example int m_Clk; // master clock frequency, hertz (148.344 is common) int m_ADCdel; // ADC setup delay, in milliseconds int m_cfp; // continuous frequency programm if not zero double m_Z0; // basis for reflection coefficnent, center of Smith Chart (usually 50.0) double m_Cop; // fringe capacitance, in pf, for open standard double m_Rsh; // series resistance, in Ohms, for short standard double m_Lsh; // series inductance, in nanohenries, for short standard double m_Rld; // series resistance, in Ohms, od the load stadard (usually 50) double m_Lld; // series inductance, in nanohenries, for the load standard double m_Cld; // shunt capacitance, in pf, over the load standard int m_Raw; // raw flag /* * Internal variables. */ FILE *m_fp; char *m_pFileName; int m_lineno; public: CVNACFG () { /* * Default values. */ m_Port = 0x378; m_Clk = 148344000; m_ADCdel = 10; m_cfp = 1; m_Z0 = 50.0; m_Cop = 0.0; m_Rsh = 0.0; m_Lsh = 0.0; m_Rld = 50.0; m_Lld = 0.0; m_Cld = 0.0; m_Raw = 0; m_pFileName = new char[strlen (VNACFGFILENAME) + 1]; strcpy (m_pFileName, VNACFGFILENAME); } ~CVNACFG () { if (m_pFileName) delete [] m_pFileName; } int getPort () {return m_Port;} int getClk () {return m_Clk;} int getADCdel () {return m_ADCdel;} int getcfp () {return m_cfp;} double getZ0 () {return m_Z0;} double getCop () {return m_Cop;} double getRsh () {return m_Rsh;} double getLsh () {return m_Lsh;} double getRld () {return m_Rld;} double getLld () {return m_Lld;} double getCld () {return m_Cld;} int getRaw () {return m_Raw;} void setPort (int v) {m_Port = v;} void setClk (int v) {m_Clk = v;} void setADCdel (int v) {m_ADCdel = v;} void setcfp (int v) {m_cfp = v;} void setZ0 (double v) {m_Z0 = v;} void setCop (double v) {m_Cop = v;} void setRsh (double v) {m_Rsh = v;} void setLsh (double v) {m_Lsh = v;} void setRld (double v) {m_Rld = v;} void setLld (double v) {m_Lld = v;} void setCld (double v) {m_Cld = v;} void setRaw (int v) {m_Raw = v;} char *getFileName () {return m_pFileName;} void setFileName (char *p) { if (m_pFileName) delete [] m_pFileName; m_pFileName = new char[strlen (p) + 1]; strcpy (m_pFileName, p); } /* * Read a configuration file. Return zero if an error. Currently, the only error * is that we were called, but asked to read neither folder. * * readfolderfile: set nonzero if we should try to read the VNA.CFG next to the executable. * fdname: name of a folder to prepend to the configuration file name. */ int ReadCFGFile (int readfolderfile, char *fdname, int *ecode = NULL) { char buff[_MAX_PATH]; if (ecode) *ecode = VEC_NOERROR; /* * Look for a trivial call, which seems like an error. */ if ((readfolderfile == 0) && (fdname == NULL)) { if (ecode) *ecode = VEC_DONOTHING; return 0; } /* * First, see if we were asked to read a VNA.CFG file in * the folder containing the executable. */ if (readfolderfile) { /* * Windows specific. */ if (GetModuleFileName (NULL, buff, _MAX_PATH) != 0) { char drive[_MAX_PATH], dir[_MAX_PATH]; _splitpath (buff, drive, dir, NULL, NULL); _makepath (buff, drive, dir, NULL, NULL); FormFileName (buff); if ((m_fp = ::fopen (buff, "r")) != (FILE *) 0) { Read (); fclose (m_fp); } } } /* * If a folder name is passed in, try that second. */ if (fdname) { strcpy (buff, fdname); FormFileName (buff); if ((m_fp = ::fopen (buff, "r")) != (FILE *) 0) { Read (); fclose (m_fp); } } return 1; } void FormFileName (char *buff) { char *p; for (p = buff; *p; p++); p--; if (*p != '\\') { p++; *p = '\\'; // Windows specific path separator } p++; strcpy (p, VNACFGFILENAME); } void Read () { while (ScanNVPair ()); } int ScanNVPair () { int c, i, ndp, ihx; float d; char nbuff[_MAX_PATH], vbuff[_MAX_PATH]; while (1) { if ((c = xgetc ()) == EOF) return 0; /* * Flush comments. */ if (c == '(') { while (1) { if ((c = xgetc ()) == EOF) return 0; if (c == ')') break; } continue; } if (!isalpha (c)) continue; /* * Start of a name. */ i = 0; nbuff[i++] = c; while (1) { if ((c = xgetc ()) == EOF) return 0; if (!isalnum (c)) break; nbuff[i++] = c; if (i >= _MAX_PATH-1) return 0; } nbuff[i] = 0; while (c != '=') { if ((c = xgetc ()) == EOF) return 0; } while (!isdigit(c) && !(c == '.') && !(c == 'x') && !(c == 'X')) { if ((c = xgetc ()) == EOF) return 0; } i = 0; vbuff[i++] = c; while (1) { /* * Can a value end with EOF? Ok, don't demand a comment or newline. */ if ((c = xgetc ()) == EOF) break; // return 0; if (!isdigit (c) && !(c == '.') && !(c == 'x') && !(c == 'X')) break; vbuff[i++] = c; if (i >= _MAX_PATH-1) return 0; } vbuff[i] = 0; /* * Look at the value. We can have decimal values, floating point, or hex. */ ihx = 0; if (vbuff[0] == '0') { if (vbuff[1] == 'x' || vbuff[1] == 'X') ihx = 1; } for (i = 0, ndp = 0; vbuff[i]; i++) { if (vbuff[i] == '.') ndp++; } if (ihx && ndp) continue; i = 0; d = 0.0; if (ihx) { sscanf (vbuff, "%x", &i); } else { if (ndp) { sscanf (vbuff, "%f", &d); } else { sscanf (vbuff, "%d", &i); } } // debugf ("NAME: %s, VALUE: %s ihx = %d, ndp = %d, i = %d, d = %f\n", nbuff, vbuff, ihx, ndp, i , d); /* * We have a name buffer, and a value buffer. Do case insensitive compares for fun. */ if (stricmp (nbuff, "Port") == 0) { if (ndp) continue; m_Port = i; continue; } if (stricmp (nbuff, "Clk") == 0) { if (ndp) m_Clk = (int) (d * 1000000.0); else m_Clk = i; continue; } if (stricmp (nbuff, "ADCdel") == 0) { if (ndp) continue; m_ADCdel = i; continue; } if (stricmp (nbuff, "cfp") == 0) { if (ndp) continue; m_cfp = i; continue; } if (stricmp (nbuff, "Z0") == 0) { if (ndp) m_Z0 = d; else m_Z0 = i; continue; } if (stricmp (nbuff, "Cop") == 0) { if (ndp) m_Cop = d; else m_Cop = i; continue; } if (stricmp (nbuff, "Rsh") == 0) { if (ndp) m_Rsh = d; else m_Rsh = i; continue; } if (stricmp (nbuff, "Lsh") == 0) { if (ndp) m_Lsh = d; else m_Lsh = i; continue; } if (stricmp (nbuff, "Rld") == 0) { if (ndp) m_Rld = d; else m_Rld = i; continue; } if (stricmp (nbuff, "Lld") == 0) { if (ndp) m_Lld = d; else m_Lld = i; continue; } if (stricmp (nbuff, "Cld") == 0) { if (ndp) m_Cld = d; else m_Cld = i; continue; } if (stricmp (nbuff, "Raw") == 0) { if (ndp) continue; m_Raw = i; continue; } } return 0; } int xgetc () { int c; c = fgetc (m_fp); if (c == '\n') m_lineno++; return c; } };