Download: project files
netlist2
tests some parsing routine for netlist files.
makefile
CFLAGS= /EHsc /W4 /nologo netlist2.exe: netlist2.cpp strtoken.cpp strtrm.cpp cl $(CFLAGS) netlist2.cpp strtoken.cpp strtrm.cpp
netlist2.cpp
01: #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.cpp
char *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.cpp
char *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