Loading CHANGELOG.txt +8 −0 Original line number Original line Diff line number Diff line Loading @@ -4,6 +4,14 @@ KiCad ChangeLog 2010 Please add newer entries at the top, list the date and your name with Please add newer entries at the top, list the date and your name with email address. email address. 2010-Oct-20 UPDATE Dick Hollenbeck <dick@softplc.com> ================================================================================ ++richio: LINE_READERs will now allocate a smaller initial size buffer, say 5000 bytes, and then resize their buffers up to some provided maximum, after which an exception is thrown should a line exceed that maximum line length. 2010-oct-15, UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr> 2010-oct-15, UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr> ================================================================================ ================================================================================ ++gerbview: ++gerbview: Loading common/dsnlexer.cpp +10 −13 Original line number Original line Diff line number Diff line Loading @@ -86,11 +86,10 @@ void DSNLEXER::PushReader( LINE_READER* aLineReader ) { { readerStack.push_back( aLineReader ); readerStack.push_back( aLineReader ); reader = aLineReader; reader = aLineReader; start = (char*) (*aLineReader); // force a new readLine() as first thing. // force a new readLine() as first thing. limit = start; limit = start(); next = start; next = start(); } } Loading @@ -103,11 +102,9 @@ bool DSNLEXER::PopReader() reader = &readerStack.back(); reader = &readerStack.back(); start = (char*) (*reader); // force a new readLine() as first thing. // force a new readLine() as first thing. limit = start; limit = start(); next = start; next = start(); return true; return true; } } return false; return false; Loading Loading @@ -334,7 +331,7 @@ L_read: goto exit; goto exit; } } cur = start; cur = start(); // skip leading whitespace // skip leading whitespace while( cur<limit && isSpace(*cur) ) while( cur<limit && isSpace(*cur) ) Loading @@ -348,8 +345,8 @@ L_read: { { // save the entire line, including new line as the current token. // save the entire line, including new line as the current token. // the '#' character may not be at offset zero. // the '#' character may not be at offset zero. curText = start; // entire line is the token curText = start(); // entire line is the token cur = start; // ensure a good curOffset below cur = start(); // ensure a good curOffset below curTok = DSN_COMMENT; curTok = DSN_COMMENT; head = limit; // do a readLine() on next call in here. head = limit; // do a readLine() on next call in here. goto exit; goto exit; Loading Loading @@ -417,7 +414,7 @@ L_read: like: U2-14 or "U2"-"14" like: U2-14 or "U2"-"14" This is detectable by a non-space immediately preceeding the dash. This is detectable by a non-space immediately preceeding the dash. */ */ if( *cur == '-' && cur>start && !isSpace( cur[-1] ) ) if( *cur == '-' && cur>start() && !isSpace( cur[-1] ) ) { { curText = '-'; curText = '-'; curTok = DSN_DASH; curTok = DSN_DASH; Loading Loading @@ -538,7 +535,7 @@ L_read: exit: // single point of exit, no returns elsewhere please. exit: // single point of exit, no returns elsewhere please. curOffset = cur - start; curOffset = cur - start(); next = head; next = head; Loading common/richio.cpp +60 −25 Original line number Original line Diff line number Diff line Loading @@ -37,10 +37,18 @@ LINE_READER::LINE_READER( unsigned aMaxLineLength ) LINE_READER::LINE_READER( unsigned aMaxLineLength ) { { lineNum = 0; lineNum = 0; if( aMaxLineLength == 0 ) // caller is goofed up. aMaxLineLength = LINE_READER_LINE_DEFAULT_MAX; maxLineLength = aMaxLineLength; maxLineLength = aMaxLineLength; // the real capacity is 10 bytes larger than requested. // start at the INITIAL size, expand as needed up to the MAX size in maxLineLength capacity = aMaxLineLength + 10; capacity = LINE_READER_LINE_INITIAL_SIZE; // but never go above user's aMaxLineLength, and leave space for trailing nul if( capacity > aMaxLineLength-1 ) capacity = aMaxLineLength-1; line = new char[capacity]; line = new char[capacity]; Loading @@ -49,6 +57,28 @@ LINE_READER::LINE_READER( unsigned aMaxLineLength ) } } void LINE_READER::expandCapacity( unsigned newsize ) { // length can equal maxLineLength and nothing breaks, there's room for // the terminating nul. cannot go over this. if( newsize > maxLineLength+1 ) newsize = maxLineLength+1; if( newsize > capacity ) { capacity = newsize; // resize the buffer, and copy the original data char* bigger = new char[capacity]; memcpy( bigger, line, length ); delete line; line = bigger; } } FILE_LINE_READER::FILE_LINE_READER( FILE* aFile, const wxString& aFileName, unsigned aMaxLineLength ) : FILE_LINE_READER::FILE_LINE_READER( FILE* aFile, const wxString& aFileName, unsigned aMaxLineLength ) : LINE_READER( aMaxLineLength ), LINE_READER( aMaxLineLength ), fp( aFile ) fp( aFile ) Loading @@ -57,56 +87,61 @@ FILE_LINE_READER::FILE_LINE_READER( FILE* aFile, const wxString& aFileName, unsi } } int FILE_LINE_READER::ReadLine() throw (IOError) unsigned FILE_LINE_READER::ReadLine() throw (IOError) { { const char* p = fgets( line, capacity, fp ); if( !p ) { line[0] = 0; length = 0; length = 0; } line[0] = 0; else // fgets always put a terminating nul at end of its read. while( fgets( line + length, capacity - length, fp ) ) { { length = strlen( line ); length += strlen( line + length ); if( length > maxLineLength ) if( length == maxLineLength ) throw IOError( _("Line length exceeded") ); throw IOError( _("Line length exceeded") ); ++lineNum; // a normal line breaks here, once through if( length < capacity-1 || line[length-1] == '\n' ) break; expandCapacity( capacity * 2 ); } } if( length ) ++lineNum; return length; return length; } } int STRING_LINE_READER::ReadLine() throw (IOError) unsigned STRING_LINE_READER::ReadLine() throw (IOError) { { size_t nlOffset = lines.find( '\n', ndx ); size_t nlOffset = lines.find( '\n', ndx ); size_t advance; if( nlOffset == std::string::npos ) if( nlOffset == std::string::npos ) advance = lines.length() - ndx; length = lines.length() - ndx; else else advance = nlOffset - ndx + 1; // include the newline, so +1 length = nlOffset - ndx + 1; // include the newline, so +1 if( advance ) if( length ) { { if( advance > maxLineLength ) if( length >= maxLineLength ) throw IOError( _("Line length exceeded") ); throw IOError( _("Line length exceeded") ); wxASSERT( ndx + advance <= lines.length() ); if( length > capacity ) expandCapacity( length ); wxASSERT( ndx + length <= lines.length() ); memcpy( line, &source[ndx], advance ); memcpy( line, &source[ndx], length ); ++lineNum; ++lineNum; ndx += advance; ndx += length; } } length = advance; line[length] = 0; line[advance] = 0; return advance; return length; } } Loading include/dsnlexer.h +12 −6 Original line number Original line Diff line number Diff line Loading @@ -79,7 +79,6 @@ enum DSN_SYNTAX_T { class DSNLEXER class DSNLEXER { { char* next; char* next; char* start; char* limit; char* limit; typedef boost::ptr_vector<LINE_READER> READER_STACK; typedef boost::ptr_vector<LINE_READER> READER_STACK; Loading @@ -100,14 +99,21 @@ class DSNLEXER const KEYWORD* keywords; const KEYWORD* keywords; unsigned keywordCount; unsigned keywordCount; /// Use casting char* operator to get start of line, which is dynamic since reader /// can be resizing its buffer at each reader->ReadLine() only. char* start() const { return (char*) (*reader); } void init(); void init(); int readLine() throw (IOError) int readLine() throw (IOError) { { int len = reader->ReadLine(); unsigned len = reader->ReadLine(); next = start; // set next and limit to start() and start() + len. limit = start + len; // start() is constant until the next ReadLine(), which could resize and // relocate reader's line buffer. next = start(); limit = next + len; return len; return len; } } Loading include/richio.h +22 −15 Original line number Original line Diff line number Diff line Loading @@ -61,6 +61,8 @@ struct IOError } } }; }; #define LINE_READER_LINE_DEFAULT_MAX 100000 #define LINE_READER_LINE_INITIAL_SIZE 5000 /** /** * Class LINE_READER * Class LINE_READER Loading @@ -70,13 +72,18 @@ struct IOError class LINE_READER class LINE_READER { { protected: protected: unsigned length; unsigned length; ///< no. bytes in line before trailing nul. int lineNum; int lineNum; char* line; unsigned maxLineLength; char* line; ///< the read line of UTF8 text unsigned capacity; unsigned capacity; ///< no. bytes allocated for line. unsigned maxLineLength; ///< maximum allowed capacity using resizing. wxString source; ///< origin of text lines, e.g. filename or "clipboard" wxString source; ///< origin of text lines, e.g. filename or "clipboard" void expandCapacity( unsigned newsize ); public: public: /** /** Loading @@ -84,7 +91,7 @@ public: * builds a line reader and fixes the length of the maximum supported * builds a line reader and fixes the length of the maximum supported * line length to @a aMaxLineLength. * line length to @a aMaxLineLength. */ */ LINE_READER( unsigned aMaxLineLength ); LINE_READER( unsigned aMaxLineLength = LINE_READER_LINE_DEFAULT_MAX ); virtual ~LINE_READER() virtual ~LINE_READER() { { Loading @@ -96,10 +103,10 @@ public: * reads a line of text into the buffer and increments the line number * reads a line of text into the buffer and increments the line number * counter. If the line is larger than the buffer size, then an exception * counter. If the line is larger than the buffer size, then an exception * is thrown. * is thrown. * @return int - The number of bytes read, 0 at end of file. * @return unsigned - The number of bytes read, 0 at end of file. * @throw IOError only when a line is too long. * @throw IOError only when a line is too long. */ */ virtual int ReadLine() throw (IOError) = 0; virtual unsigned ReadLine() throw (IOError) = 0; /** /** * Function GetSource * Function GetSource Loading @@ -118,7 +125,7 @@ public: * is a casting operator that returns a char* pointer to the start of the * is a casting operator that returns a char* pointer to the start of the * line buffer. * line buffer. */ */ operator char* () operator char* () const { { return line; return line; } } Loading Loading @@ -166,7 +173,7 @@ public: * @param aFileName is the name of the file for error reporting purposes. * @param aFileName is the name of the file for error reporting purposes. * @param aMaxLineLength is the number of bytes to use in the line buffer. * @param aMaxLineLength is the number of bytes to use in the line buffer. */ */ FILE_LINE_READER( FILE* aFile, const wxString& aFileName, unsigned aMaxLineLength ); FILE_LINE_READER( FILE* aFile, const wxString& aFileName, unsigned aMaxLineLength = LINE_READER_LINE_DEFAULT_MAX ); ~FILE_LINE_READER() ~FILE_LINE_READER() { { Loading @@ -179,10 +186,10 @@ public: * reads a line of text into the buffer and increments the line number * reads a line of text into the buffer and increments the line number * counter. If the line is larger than the buffer size, then an exception * counter. If the line is larger than the buffer size, then an exception * is thrown. * is thrown. * @return int - The number of bytes read, 0 at end of file. * @return unsigned - The number of bytes read, 0 at end of file. * @throw IOError only when a line is too long. * @throw IOError only when a line is too long. */ */ int ReadLine() throw (IOError); unsigned ReadLine() throw (IOError); /** /** * Function Rewind * Function Rewind Loading Loading @@ -234,10 +241,10 @@ public: * reads a line of text into the buffer and increments the line number * reads a line of text into the buffer and increments the line number * counter. If the line is larger than the buffer size, then an exception * counter. If the line is larger than the buffer size, then an exception * is thrown. * is thrown. * @return int - The number of bytes read, 0 at end of file. * @return unsigned - The number of bytes read, 0 at end of file. * @throw IOError only when a line is too long. * @throw IOError only when a line is too long. */ */ int ReadLine() throw (IOError); unsigned ReadLine() throw (IOError); }; }; Loading Loading
CHANGELOG.txt +8 −0 Original line number Original line Diff line number Diff line Loading @@ -4,6 +4,14 @@ KiCad ChangeLog 2010 Please add newer entries at the top, list the date and your name with Please add newer entries at the top, list the date and your name with email address. email address. 2010-Oct-20 UPDATE Dick Hollenbeck <dick@softplc.com> ================================================================================ ++richio: LINE_READERs will now allocate a smaller initial size buffer, say 5000 bytes, and then resize their buffers up to some provided maximum, after which an exception is thrown should a line exceed that maximum line length. 2010-oct-15, UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr> 2010-oct-15, UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr> ================================================================================ ================================================================================ ++gerbview: ++gerbview: Loading
common/dsnlexer.cpp +10 −13 Original line number Original line Diff line number Diff line Loading @@ -86,11 +86,10 @@ void DSNLEXER::PushReader( LINE_READER* aLineReader ) { { readerStack.push_back( aLineReader ); readerStack.push_back( aLineReader ); reader = aLineReader; reader = aLineReader; start = (char*) (*aLineReader); // force a new readLine() as first thing. // force a new readLine() as first thing. limit = start; limit = start(); next = start; next = start(); } } Loading @@ -103,11 +102,9 @@ bool DSNLEXER::PopReader() reader = &readerStack.back(); reader = &readerStack.back(); start = (char*) (*reader); // force a new readLine() as first thing. // force a new readLine() as first thing. limit = start; limit = start(); next = start; next = start(); return true; return true; } } return false; return false; Loading Loading @@ -334,7 +331,7 @@ L_read: goto exit; goto exit; } } cur = start; cur = start(); // skip leading whitespace // skip leading whitespace while( cur<limit && isSpace(*cur) ) while( cur<limit && isSpace(*cur) ) Loading @@ -348,8 +345,8 @@ L_read: { { // save the entire line, including new line as the current token. // save the entire line, including new line as the current token. // the '#' character may not be at offset zero. // the '#' character may not be at offset zero. curText = start; // entire line is the token curText = start(); // entire line is the token cur = start; // ensure a good curOffset below cur = start(); // ensure a good curOffset below curTok = DSN_COMMENT; curTok = DSN_COMMENT; head = limit; // do a readLine() on next call in here. head = limit; // do a readLine() on next call in here. goto exit; goto exit; Loading Loading @@ -417,7 +414,7 @@ L_read: like: U2-14 or "U2"-"14" like: U2-14 or "U2"-"14" This is detectable by a non-space immediately preceeding the dash. This is detectable by a non-space immediately preceeding the dash. */ */ if( *cur == '-' && cur>start && !isSpace( cur[-1] ) ) if( *cur == '-' && cur>start() && !isSpace( cur[-1] ) ) { { curText = '-'; curText = '-'; curTok = DSN_DASH; curTok = DSN_DASH; Loading Loading @@ -538,7 +535,7 @@ L_read: exit: // single point of exit, no returns elsewhere please. exit: // single point of exit, no returns elsewhere please. curOffset = cur - start; curOffset = cur - start(); next = head; next = head; Loading
common/richio.cpp +60 −25 Original line number Original line Diff line number Diff line Loading @@ -37,10 +37,18 @@ LINE_READER::LINE_READER( unsigned aMaxLineLength ) LINE_READER::LINE_READER( unsigned aMaxLineLength ) { { lineNum = 0; lineNum = 0; if( aMaxLineLength == 0 ) // caller is goofed up. aMaxLineLength = LINE_READER_LINE_DEFAULT_MAX; maxLineLength = aMaxLineLength; maxLineLength = aMaxLineLength; // the real capacity is 10 bytes larger than requested. // start at the INITIAL size, expand as needed up to the MAX size in maxLineLength capacity = aMaxLineLength + 10; capacity = LINE_READER_LINE_INITIAL_SIZE; // but never go above user's aMaxLineLength, and leave space for trailing nul if( capacity > aMaxLineLength-1 ) capacity = aMaxLineLength-1; line = new char[capacity]; line = new char[capacity]; Loading @@ -49,6 +57,28 @@ LINE_READER::LINE_READER( unsigned aMaxLineLength ) } } void LINE_READER::expandCapacity( unsigned newsize ) { // length can equal maxLineLength and nothing breaks, there's room for // the terminating nul. cannot go over this. if( newsize > maxLineLength+1 ) newsize = maxLineLength+1; if( newsize > capacity ) { capacity = newsize; // resize the buffer, and copy the original data char* bigger = new char[capacity]; memcpy( bigger, line, length ); delete line; line = bigger; } } FILE_LINE_READER::FILE_LINE_READER( FILE* aFile, const wxString& aFileName, unsigned aMaxLineLength ) : FILE_LINE_READER::FILE_LINE_READER( FILE* aFile, const wxString& aFileName, unsigned aMaxLineLength ) : LINE_READER( aMaxLineLength ), LINE_READER( aMaxLineLength ), fp( aFile ) fp( aFile ) Loading @@ -57,56 +87,61 @@ FILE_LINE_READER::FILE_LINE_READER( FILE* aFile, const wxString& aFileName, unsi } } int FILE_LINE_READER::ReadLine() throw (IOError) unsigned FILE_LINE_READER::ReadLine() throw (IOError) { { const char* p = fgets( line, capacity, fp ); if( !p ) { line[0] = 0; length = 0; length = 0; } line[0] = 0; else // fgets always put a terminating nul at end of its read. while( fgets( line + length, capacity - length, fp ) ) { { length = strlen( line ); length += strlen( line + length ); if( length > maxLineLength ) if( length == maxLineLength ) throw IOError( _("Line length exceeded") ); throw IOError( _("Line length exceeded") ); ++lineNum; // a normal line breaks here, once through if( length < capacity-1 || line[length-1] == '\n' ) break; expandCapacity( capacity * 2 ); } } if( length ) ++lineNum; return length; return length; } } int STRING_LINE_READER::ReadLine() throw (IOError) unsigned STRING_LINE_READER::ReadLine() throw (IOError) { { size_t nlOffset = lines.find( '\n', ndx ); size_t nlOffset = lines.find( '\n', ndx ); size_t advance; if( nlOffset == std::string::npos ) if( nlOffset == std::string::npos ) advance = lines.length() - ndx; length = lines.length() - ndx; else else advance = nlOffset - ndx + 1; // include the newline, so +1 length = nlOffset - ndx + 1; // include the newline, so +1 if( advance ) if( length ) { { if( advance > maxLineLength ) if( length >= maxLineLength ) throw IOError( _("Line length exceeded") ); throw IOError( _("Line length exceeded") ); wxASSERT( ndx + advance <= lines.length() ); if( length > capacity ) expandCapacity( length ); wxASSERT( ndx + length <= lines.length() ); memcpy( line, &source[ndx], advance ); memcpy( line, &source[ndx], length ); ++lineNum; ++lineNum; ndx += advance; ndx += length; } } length = advance; line[length] = 0; line[advance] = 0; return advance; return length; } } Loading
include/dsnlexer.h +12 −6 Original line number Original line Diff line number Diff line Loading @@ -79,7 +79,6 @@ enum DSN_SYNTAX_T { class DSNLEXER class DSNLEXER { { char* next; char* next; char* start; char* limit; char* limit; typedef boost::ptr_vector<LINE_READER> READER_STACK; typedef boost::ptr_vector<LINE_READER> READER_STACK; Loading @@ -100,14 +99,21 @@ class DSNLEXER const KEYWORD* keywords; const KEYWORD* keywords; unsigned keywordCount; unsigned keywordCount; /// Use casting char* operator to get start of line, which is dynamic since reader /// can be resizing its buffer at each reader->ReadLine() only. char* start() const { return (char*) (*reader); } void init(); void init(); int readLine() throw (IOError) int readLine() throw (IOError) { { int len = reader->ReadLine(); unsigned len = reader->ReadLine(); next = start; // set next and limit to start() and start() + len. limit = start + len; // start() is constant until the next ReadLine(), which could resize and // relocate reader's line buffer. next = start(); limit = next + len; return len; return len; } } Loading
include/richio.h +22 −15 Original line number Original line Diff line number Diff line Loading @@ -61,6 +61,8 @@ struct IOError } } }; }; #define LINE_READER_LINE_DEFAULT_MAX 100000 #define LINE_READER_LINE_INITIAL_SIZE 5000 /** /** * Class LINE_READER * Class LINE_READER Loading @@ -70,13 +72,18 @@ struct IOError class LINE_READER class LINE_READER { { protected: protected: unsigned length; unsigned length; ///< no. bytes in line before trailing nul. int lineNum; int lineNum; char* line; unsigned maxLineLength; char* line; ///< the read line of UTF8 text unsigned capacity; unsigned capacity; ///< no. bytes allocated for line. unsigned maxLineLength; ///< maximum allowed capacity using resizing. wxString source; ///< origin of text lines, e.g. filename or "clipboard" wxString source; ///< origin of text lines, e.g. filename or "clipboard" void expandCapacity( unsigned newsize ); public: public: /** /** Loading @@ -84,7 +91,7 @@ public: * builds a line reader and fixes the length of the maximum supported * builds a line reader and fixes the length of the maximum supported * line length to @a aMaxLineLength. * line length to @a aMaxLineLength. */ */ LINE_READER( unsigned aMaxLineLength ); LINE_READER( unsigned aMaxLineLength = LINE_READER_LINE_DEFAULT_MAX ); virtual ~LINE_READER() virtual ~LINE_READER() { { Loading @@ -96,10 +103,10 @@ public: * reads a line of text into the buffer and increments the line number * reads a line of text into the buffer and increments the line number * counter. If the line is larger than the buffer size, then an exception * counter. If the line is larger than the buffer size, then an exception * is thrown. * is thrown. * @return int - The number of bytes read, 0 at end of file. * @return unsigned - The number of bytes read, 0 at end of file. * @throw IOError only when a line is too long. * @throw IOError only when a line is too long. */ */ virtual int ReadLine() throw (IOError) = 0; virtual unsigned ReadLine() throw (IOError) = 0; /** /** * Function GetSource * Function GetSource Loading @@ -118,7 +125,7 @@ public: * is a casting operator that returns a char* pointer to the start of the * is a casting operator that returns a char* pointer to the start of the * line buffer. * line buffer. */ */ operator char* () operator char* () const { { return line; return line; } } Loading Loading @@ -166,7 +173,7 @@ public: * @param aFileName is the name of the file for error reporting purposes. * @param aFileName is the name of the file for error reporting purposes. * @param aMaxLineLength is the number of bytes to use in the line buffer. * @param aMaxLineLength is the number of bytes to use in the line buffer. */ */ FILE_LINE_READER( FILE* aFile, const wxString& aFileName, unsigned aMaxLineLength ); FILE_LINE_READER( FILE* aFile, const wxString& aFileName, unsigned aMaxLineLength = LINE_READER_LINE_DEFAULT_MAX ); ~FILE_LINE_READER() ~FILE_LINE_READER() { { Loading @@ -179,10 +186,10 @@ public: * reads a line of text into the buffer and increments the line number * reads a line of text into the buffer and increments the line number * counter. If the line is larger than the buffer size, then an exception * counter. If the line is larger than the buffer size, then an exception * is thrown. * is thrown. * @return int - The number of bytes read, 0 at end of file. * @return unsigned - The number of bytes read, 0 at end of file. * @throw IOError only when a line is too long. * @throw IOError only when a line is too long. */ */ int ReadLine() throw (IOError); unsigned ReadLine() throw (IOError); /** /** * Function Rewind * Function Rewind Loading Loading @@ -234,10 +241,10 @@ public: * reads a line of text into the buffer and increments the line number * reads a line of text into the buffer and increments the line number * counter. If the line is larger than the buffer size, then an exception * counter. If the line is larger than the buffer size, then an exception * is thrown. * is thrown. * @return int - The number of bytes read, 0 at end of file. * @return unsigned - The number of bytes read, 0 at end of file. * @throw IOError only when a line is too long. * @throw IOError only when a line is too long. */ */ int ReadLine() throw (IOError); unsigned ReadLine() throw (IOError); }; }; Loading