Download: project files
netlist2 tests some parsing routine for netlist files.
makefileCFLAGS= /EHsc /W4 /nologo netlist2.exe: netlist2.cpp strtoken.cpp strtrm.cpp cl $(CFLAGS) netlist2.cpp strtoken.cpp strtrm.cpp
netlist2.cpp01: #include <stdio.h>
02: #include <stdlib.h>
03: #include <string>
04: using namespace std;
05:
06:
07: char *strtrm(char *str, char delimiter);
08: char *strtoken(char* &inp, char delimiter);
09:
10:
11:
12: void netlist2(FILE *in);
13:
14:
15: int main(int argc, char *argv[])
16: {
17: char *filename;
18: FILE *in;
19: if (argc>1) {
20: filename = argv[1];
21: errno_t nerr = fopen_s(&in,filename,"r");
22: if (nerr) {
23: printf("file: %s not found\n",filename);
24: return EXIT_FAILURE;
25: }
26: }
27: else {
28: filename = "stdin";
29: in = stdin;
30: }
31: netlist2(in);
32: fclose(in);
33: return EXIT_SUCCESS;
34: }
35:
36: void netlist2(FILE *in)
37: {
38: char buf[512];
39: char *inp, *token;
40: bool done = false;
41: int lines = 0;
42: while (!done) {
43: fgets(buf,511,in);
44: if (feof(in)) return;
45: lines++;
46: strtrm(buf,'\n'); // terminate at newline character
47: printf("line %d: %s\n",lines, buf);
48: strtrm(buf,'%'); // terminate at comment character
49: int n=0;
50: inp = buf;
51: string tok[16];
52: while ((token=strtoken(inp,' '))!=0) {
53: tok[n++] = token;
54: printf("token %d: %s\n",n,token);
55: }
56: }
57: }
strtoken.cppchar *strtoken(char* &str, char delimiter)
skips whitespace and returns next token (or null pointer)
str | input c-string (modified to point to character after the delimiter) |
delimiter | marks the end of a token (usually a blank) |
retval | c-string to character following the delimiter |
The delimiter character in the input string is replaced by a null character.
01: /* \file strtoken.cpp
02: *
03: */
04: #include <stdio.h>
05: #include <stdlib.h>
06:
07: //! skips whitespace and returns next token (or null pointer)
08: /*!
09: * \param str is input c-string (modified to point to character after
10: * delimiter
11: * \param delimiter marks the end of a token (usually a blank)
12: * \retval c-string pointing to start of delimiter.
13: * The delimiter character in the input string is replaced by a null
14: * character.
15: */
16:
17: char *strtoken(char* &str, char delimiter)
18: {
19: //char *str = *inp;
20: if (str==0) return 0;
21: while (*str == ' ') str++; // skip whitespace
22: //*inp = str;
23: if (*str==0) return 0;
24: char *token = str;
25: while (*str && *str!=delimiter) str++;
26: if (*str) *str++ = 0; // substitute null for delimiter to terminate token
27: //*inp = str;
28: return token;
29: }
30:
strtrm.cppchar *strtrm(char *str, char delimiter)terminates string at specified character
This routine terminates a string at the specified character and returns a c-string pointer to the character following the delimiter.
str | input c-string |
delimiter | marks the end of a token |
retval | c-string to character following the delimiter |
For example: Suppose the string str = "name=value"; then
char * token = strtrm(str,"=");would return "value" as the token, but
str would now be "name" since
the character '=' is replaced by a null.
01: /* util.cpp
02: *
03: */
04: #include <stdio.h>
05: #include <stdlib.h>
06: //#include "util.h"
07:
08: //! terminates string at specified character
09: /*! This routine terminates a string at the specified character and
10: * returns a c-string pointer to the character following the delimiter.
11: * @param str input c-string
12: * @retval c-string to character following the delimiter
13: *
14: * For example: Suppose the string str = "name=value";
15: * then char * token = strtrm(str,"=");
16: * would return "value" as the token, but str would now be "name" since
17: * the character '=' is replaced by a null.
18: */
19:
20: char *strtrm(char *str, char delimiter)
21: {
22: if (str==0) return 0;
23: while (*str && *str!=delimiter) str++;
24: if (*str==0) return 0;
25: *str++ = 0;
26: return str;
27: }
28:
29:
30: //! count occurences of specified character in a string.
31:
32: int strcnt(char *str, char delimiter)
33: {
34: int n = 0;
35: while (*str) {
36: if (*str++ == delimiter) n++;
37: }
38: return n;
39: }
40:
41: //! return pointer to character after delimiter, ignoring quoted text
42: /*!
43: * This routine returns a pointer (c-string) to character after the
44: * delimiter, ignoring text between quotes. Returns null if delimiter not found.
45: */
46:
47: char *strqtrm(char *str, char delimiter)
48: {
49: if (str==0) return 0;
50: while (*str && *str!=delimiter) {
51: if (*str=='\"') {
52: str++;
53: while (*str && *str!='\"') str++;
54: if (*str==0) return 0;
55: }
56: str++;
57: }
58: if (*str==0) return 0;
59: *str++ = 0;
60: return str;
61: }
62:
63:
64: //! convert two digit hex string to an ASCII character
65:
66: char x2c(char *str)
67: {
68: char digit;
69: /* The operation (*str & 0xdf) converts lower case to upper case */
70: digit = (*str >= 'A' ? ((*str & 0xdf) - 'A')+10 : (*str - '0'));
71: digit *= 16;
72: str++;
73: digit += (*str >= 'A' ? ((*str & 0xdf) - 'A')+10 : (*str - '0'));
74: return(digit);
75: }
76:
77: //! convert '+' to ' ' and two digit hex escape sequences to ASCII character
78:
79: void unescape_url(char *url)
80: {
81: char *cp;
82: for (cp=url; *url; cp++, url++) {
83: if (*url == '+') *cp = ' ';
84: else if (*url == '%') {
85: *cp = x2c(url+1);
86: url += 2;
87: }
88: else *cp = *url;
89: }
90: *cp = '\0';
91: }
Input (test.net):
% This is a test of circuit file parser R R1 N_2 N_1 3k R R2 N_2 N_3 4MEG V V1 N_1 N_3 5 R R3 N_3 0 2
Run netlist2 test.net > test.txt
Output
line 1: % This is a test of circuit file parser line 2: R R1 N_2 N_1 3k token 1: R token 2: R1 token 3: N_2 token 4: N_1 token 5: 3k line 3: R R2 N_2 N_3 4MEG token 1: R token 2: R2 token 3: N_2 token 4: N_3 token 5: 4MEG line 4: V V1 N_1 N_3 5 token 1: V token 2: V1 token 3: N_1 token 4: N_3 token 5: 5 line 5: R R3 N_3 0 2 token 1: R token 2: R3 token 3: N_3 token 4: 0 token 5: 2
Maintained by John Loomis, updated Tue Feb 19 22:08:03 2008