/* * This program source code file is part of KICAD, a free EDA CAD application. * * Copyright (C) 2007-2010 SoftPLC Corporation, Dick Hollenbeck * Copyright (C) 2007 Kicad Developers, see change_log.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, you may find one here: * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html * or you may search the http://www.gnu.org website for the version 2 license, * or you may write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef RICHIO_H_ #define RICHIO_H_ // This file defines 3 classes useful for working with DSN text files and is named // "richio" after its author, Richard Hollenbeck, aka Dick Hollenbeck. #include #include // I really did not want to be dependent on wxWidgets in richio // but the errorText needs to be wide char so wxString rules. #include #include // FILE /** * Struct IOError * is a class used to hold an error message and may be used to throw exceptions * containing meaningful error messages. */ struct IOError { wxString errorText; IOError( const wxChar* aMsg ) : errorText( aMsg ) { } IOError( const wxString& aMsg ) : errorText( aMsg ) { } }; /** * Class LINE_READER * reads single lines of text into its buffer and increments a line number counter. * It throws an exception if a line is too long. */ class LINE_READER { protected: FILE* fp; int lineNum; unsigned maxLineLength; unsigned length; char* line; unsigned capacity; public: /** * Constructor LINE_READER * takes an open FILE and the size of the desired line buffer. * @param aFile An open file in "ascii" mode, not binary mode. * @param aMaxLineLength The number of bytes to use in the line buffer. */ LINE_READER( FILE* aFile, unsigned aMaxLineLength ); ~LINE_READER() { delete[] line; } /* int CharAt( int aNdx ) { if( (unsigned) aNdx < capacity ) return (char) (unsigned char) line[aNdx]; return -1; } */ /** * Function ReadLine * 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 * is thrown. * @return int - The number of bytes read, 0 at end of file. * @throw IOError only when a line is too long. */ int ReadLine() throw (IOError); operator char* () { return line; } int LineNumber() { return lineNum; } unsigned Length() { return length; } }; /** * Class OUTPUTFORMATTER * is an interface (abstract class) used to output ASCII text in a convenient * way. The primary interface is printf() like but with support for indentation * control. The destination of the 8 bit wide text is up to the implementer. * If you want to output a wxString, then use CONV_TO_UTF8() on it before passing * it as an argument to Print(). *

* Since this is an abstract interface, only classes derived from this one * will be the implementations. */ class OUTPUTFORMATTER { #if defined(__GNUG__) // The GNU C++ compiler defines this // When used on a C++ function, we must account for the "this" pointer, // so increase the STRING-INDEX and FIRST-TO_CHECK by one. // See http://docs.freebsd.org/info/gcc/gcc.info.Function_Attributes.html // Then to get format checking during the compile, compile with -Wall or -Wformat #define PRINTF_FUNC __attribute__ ((format (printf, 3, 4))) #else #define PRINTF_FUNC // nothing #endif public: /** * Function Print * formats and writes text to the output stream. * * @param nestLevel The multiple of spaces to preceed the output with. * @param fmt A printf() style format string. * @param ... a variable list of parameters that will get blended into * the output under control of the format string. * @return int - the number of characters output. * @throw IOError, if there is a problem outputting, such as a full disk. */ virtual int PRINTF_FUNC Print( int nestLevel, const char* fmt, ... ) throw( IOError ) = 0; /** * Function GetQuoteChar * performs quote character need determination. * It returns the quote character as a single character string for a given * input wrapee string. If the wrappee does not need to be quoted, * the return value is "" (the null string), such as when there are no * delimiters in the input wrapee string. If you want the quote_char * to be assuredly not "", then pass in "(" as the wrappee. *

* Implementations are free to override the default behavior, which is to * call the static function of the same name. * @param wrapee A string that might need wrapping on each end. * @return const char* - the quote_char as a single character string, or "" * if the wrapee does not need to be wrapped. */ virtual const char* GetQuoteChar( const char* wrapee ) = 0; virtual ~OUTPUTFORMATTER() {} /** * Function GetQuoteChar * performs quote character need determination according to the Specctra DSN * specification. * @param wrapee A string that might need wrapping on each end. * @param quote_char A single character C string which provides the current * quote character, should it be needed by the wrapee. * * @return const char* - the quote_char as a single character string, or "" * if the wrapee does not need to be wrapped. */ static const char* GetQuoteChar( const char* wrapee, const char* quote_char ); }; /** * Class STRINGFORMATTER * implements OUTPUTFORMATTER to a memory buffer. After Print()ing the * string is available through GetString() */ class STRINGFORMATTER : public OUTPUTFORMATTER { std::vector buffer; std::string mystring; int sprint( const char* fmt, ... ); int vprint( const char* fmt, va_list ap ); public: /** * Constructor STRINGFORMATTER * reserves space in the buffer */ STRINGFORMATTER( int aReserve = 300 ) : buffer( aReserve, '\0' ) { } /** * Function Clear * clears the buffer and empties the internal string. */ void Clear() { mystring.clear(); } /** * Function StripUseless * removes whitespace, '(', and ')' from the mystring. */ void StripUseless(); std::string GetString() { return mystring; } //----------------------------------------------------- int PRINTF_FUNC Print( int nestLevel, const char* fmt, ... ) throw( IOError ); const char* GetQuoteChar( const char* wrapee ); //---------------------------------------------------- }; #endif // RICHIO_H_