You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

401 lines
12 KiB

16 years ago
  1. /*
  2. * This program source code file is part of KICAD, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2007-2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
  5. * Copyright (C) 2007 Kicad Developers, see change_log.txt for contributors.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * as published by the Free Software Foundation; either version 2
  10. * of the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, you may find one here:
  19. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  20. * or you may search the http://www.gnu.org website for the version 2 license,
  21. * or you may write to the Free Software Foundation, Inc.,
  22. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  23. */
  24. #ifndef RICHIO_H_
  25. #define RICHIO_H_
  26. // This file defines 3 classes useful for working with DSN text files and is named
  27. // "richio" after its author, Richard Hollenbeck, aka Dick Hollenbeck.
  28. #include <string>
  29. #include <vector>
  30. // I really did not want to be dependent on wxWidgets in richio
  31. // but the errorText needs to be wide char so wxString rules.
  32. #include <wx/wx.h>
  33. #include <cstdio> // FILE
  34. /**
  35. * Struct IOError
  36. * is a class used to hold an error message and may be used to throw exceptions
  37. * containing meaningful error messages.
  38. */
  39. struct IOError
  40. {
  41. wxString errorText;
  42. IOError( const wxChar* aMsg ) :
  43. errorText( aMsg )
  44. {
  45. }
  46. IOError( const wxString& aMsg ) :
  47. errorText( aMsg )
  48. {
  49. }
  50. };
  51. /**
  52. * Class LINE_READER
  53. * reads single lines of text into its buffer and increments a line number counter.
  54. * It throws an exception if a line is too long.
  55. */
  56. class LINE_READER
  57. {
  58. protected:
  59. unsigned length;
  60. int lineNum;
  61. char* line;
  62. unsigned maxLineLength;
  63. unsigned capacity;
  64. public:
  65. LINE_READER( unsigned aMaxLineLength );
  66. virtual ~LINE_READER()
  67. {
  68. delete[] line;
  69. }
  70. /**
  71. * Function ReadLine
  72. * reads a line of text into the buffer and increments the line number
  73. * counter. If the line is larger than the buffer size, then an exception
  74. * is thrown.
  75. * @return int - The number of bytes read, 0 at end of file.
  76. * @throw IOError only when a line is too long.
  77. */
  78. virtual int ReadLine() throw (IOError) = 0;
  79. operator char* ()
  80. {
  81. return line;
  82. }
  83. int LineNumber()
  84. {
  85. return lineNum;
  86. }
  87. unsigned Length()
  88. {
  89. return length;
  90. }
  91. };
  92. /**
  93. * Class FILE_LINE_READER
  94. * is a LINE_READER that reads from an open file. File must be already open
  95. * so that this class can exist without and UI policy.
  96. */
  97. class FILE_LINE_READER : public LINE_READER
  98. {
  99. protected:
  100. FILE* fp; ///< no ownership, no close on destruction
  101. public:
  102. /**
  103. * Constructor LINE_READER
  104. * takes an open FILE and the size of the desired line buffer.
  105. * @param aFile An open file in "ascii" mode, not binary mode.
  106. * @param aMaxLineLength The number of bytes to use in the line buffer.
  107. */
  108. FILE_LINE_READER( FILE* aFile, unsigned aMaxLineLength );
  109. /**
  110. * Function ReadLine
  111. * reads a line of text into the buffer and increments the line number
  112. * counter. If the line is larger than the buffer size, then an exception
  113. * is thrown.
  114. * @return int - The number of bytes read, 0 at end of file.
  115. * @throw IOError only when a line is too long.
  116. */
  117. int ReadLine() throw (IOError);
  118. /**
  119. * Function Rewind
  120. * a wrapper to the standard function rewind.
  121. * also clear the current line number
  122. */
  123. void Rewind()
  124. {
  125. rewind( fp );
  126. lineNum = 0;
  127. }
  128. };
  129. /**
  130. * Class STRING_LINE_READER
  131. * is a LINE_READER that reads from a multiline 8 bit wide std::string
  132. */
  133. class STRING_LINE_READER : public LINE_READER
  134. {
  135. protected:
  136. std::string source;
  137. size_t ndx;
  138. public:
  139. /**
  140. * Constructor STRING_LINE_READER( const std::string& aString )
  141. * @param aString is a source string consisting of one or more lines
  142. * of text, where multiple lines are separated with a '\n' character.
  143. * The last line does not necessarily need a trailing '\n'.
  144. */
  145. STRING_LINE_READER( const std::string& aString ) :
  146. LINE_READER( 4096 ),
  147. source( aString ),
  148. ndx( 0 )
  149. {
  150. // Clipboard text should be nice and _use multiple lines_ so that
  151. // we can report _line number_ oriented error messages when parsing.
  152. // Therefore a line of 4096 characters max seems more than adequate.
  153. }
  154. /**
  155. * Function ReadLine
  156. * reads a line of text into the buffer and increments the line number
  157. * counter. If the line is larger than the buffer size, then an exception
  158. * is thrown.
  159. * @return int - The number of bytes read, 0 at end of file.
  160. * @throw IOError only when a line is too long.
  161. */
  162. int ReadLine() throw (IOError);
  163. };
  164. /**
  165. * Class OUTPUTFORMATTER
  166. * is an important interface (abstract) class used to output UTF8 text in a convenient
  167. * way. The primary interface is "printf() - like" but with support for indentation
  168. * control. The destination of the 8 bit wide text is up to the implementer.
  169. * <p>
  170. * The implementer only has to implement the write() function, but can also optionaly
  171. * re-implement GetQuoteChar().
  172. * <p>
  173. * If you want to output a wxString, then use CONV_TO_UTF8() on it before passing
  174. * it as an argument to Print().
  175. * <p>
  176. * Since this is an abstract interface, only classes derived from this one
  177. * may actually be used.
  178. */
  179. class OUTPUTFORMATTER
  180. {
  181. std::vector<char> buffer;
  182. int sprint( const char* fmt, ... ) throw( IOError );
  183. int vprint( const char* fmt, va_list ap ) throw( IOError );
  184. protected:
  185. OUTPUTFORMATTER( int aReserve = 300 ) :
  186. buffer( aReserve, '\0' )
  187. {
  188. }
  189. virtual ~OUTPUTFORMATTER() {}
  190. /**
  191. * Function GetQuoteChar
  192. * performs quote character need determination according to the Specctra DSN
  193. * specification.
  194. * @param wrapee A string that might need wrapping on each end.
  195. * @param quote_char A single character C string which provides the current
  196. * quote character, should it be needed by the wrapee.
  197. *
  198. * @return const char* - the quote_char as a single character string, or ""
  199. * if the wrapee does not need to be wrapped.
  200. */
  201. static const char* GetQuoteChar( const char* wrapee, const char* quote_char );
  202. /**
  203. * Function write
  204. * should be coded in the interface implementation (derived) classes.
  205. *
  206. * @param aOutBuf is the start of a byte buffer to write.
  207. * @param aCount tells how many bytes to write.
  208. * @throw IOError, if there is a problem outputting, such as a full disk.
  209. */
  210. virtual void write( const char* aOutBuf, int aCount ) throw( IOError ) = 0;
  211. #if defined(__GNUG__) // The GNU C++ compiler defines this
  212. // When used on a C++ function, we must account for the "this" pointer,
  213. // so increase the STRING-INDEX and FIRST-TO_CHECK by one.
  214. // See http://docs.freebsd.org/info/gcc/gcc.info.Function_Attributes.html
  215. // Then to get format checking during the compile, compile with -Wall or -Wformat
  216. #define PRINTF_FUNC __attribute__ ((format (printf, 3, 4)))
  217. #else
  218. #define PRINTF_FUNC // nothing
  219. #endif
  220. public:
  221. //-----<interface functions>------------------------------------------
  222. /**
  223. * Function Print
  224. * formats and writes text to the output stream.
  225. *
  226. * @param nestLevel The multiple of spaces to preceed the output with.
  227. * @param fmt A printf() style format string.
  228. * @param ... a variable list of parameters that will get blended into
  229. * the output under control of the format string.
  230. * @return int - the number of characters output.
  231. * @throw IOError, if there is a problem outputting, such as a full disk.
  232. */
  233. int PRINTF_FUNC Print( int nestLevel, const char* fmt, ... ) throw( IOError );
  234. /**
  235. * Function GetQuoteChar
  236. * performs quote character need determination.
  237. * It returns the quote character as a single character string for a given
  238. * input wrapee string. If the wrappee does not need to be quoted,
  239. * the return value is "" (the null string), such as when there are no
  240. * delimiters in the input wrapee string. If you want the quote_char
  241. * to be assuredly not "", then pass in "(" as the wrappee.
  242. * <p>
  243. * Implementations are free to override the default behavior, which is to
  244. * call the static function of the same name.
  245. * @param wrapee A string that might need wrapping on each end.
  246. * @return const char* - the quote_char as a single character string, or ""
  247. * if the wrapee does not need to be wrapped.
  248. */
  249. virtual const char* GetQuoteChar( const char* wrapee )
  250. {
  251. return GetQuoteChar( wrapee, "\"" );
  252. }
  253. /**
  254. * Function Quoted
  255. * checks \a aWrappee input string for a need to be quoted
  256. * (e.g. contains a ')' character or a space), and for \" double quotes
  257. * within the string that need to be doubled up such that the DSNLEXER
  258. * will correctly parse the string from a file later.
  259. *
  260. * @param aWrapee is a string that might need wraping in double quotes,
  261. * and it might need to have its internal quotes doubled up, or not.
  262. * Caller's copy may be modified, or not.
  263. *
  264. * @return const char* - useful for passing to printf() style functions that
  265. * must output utf8 streams.
  266. virtual const char* Quoted( std::string* aWrapee );
  267. thinking about using wxCharBuffer* instead.
  268. */
  269. //-----</interface functions>-----------------------------------------
  270. };
  271. /**
  272. * Class STRING_FORMATTER
  273. * implements OUTPUTFORMATTER to a memory buffer. After Print()ing the
  274. * string is available through GetString()
  275. */
  276. class STRING_FORMATTER : public OUTPUTFORMATTER
  277. {
  278. std::string mystring;
  279. public:
  280. /**
  281. * Constructor STRING_FORMATTER
  282. * reserves space in the buffer
  283. */
  284. STRING_FORMATTER( int aReserve = 300 ) :
  285. OUTPUTFORMATTER( aReserve )
  286. {
  287. }
  288. /**
  289. * Function Clear
  290. * clears the buffer and empties the internal string.
  291. */
  292. void Clear()
  293. {
  294. mystring.clear();
  295. }
  296. /**
  297. * Function StripUseless
  298. * removes whitespace, '(', and ')' from the mystring.
  299. */
  300. void StripUseless();
  301. std::string GetString()
  302. {
  303. return mystring;
  304. }
  305. //-----<OUTPUTFORMATTER>------------------------------------------------
  306. protected:
  307. void write( const char* aOutBuf, int aCount ) throw( IOError );
  308. //-----</OUTPUTFORMATTER>-----------------------------------------------
  309. };
  310. /**
  311. * Class STREAM_OUTPUTFORMATTER
  312. * implements OUTPUTFORMATTER to a wxWidgets wxOutputStream. The stream is
  313. * neither opened nor closed by this class.
  314. */
  315. class STREAM_OUTPUTFORMATTER : public OUTPUTFORMATTER
  316. {
  317. wxOutputStream& os;
  318. char quoteChar[2];
  319. public:
  320. /**
  321. * Constructor STREAM_OUTPUTFORMATTER
  322. * can take any number of wxOutputStream derivations, so it can write
  323. * to a file, socket, or zip file.
  324. */
  325. STREAM_OUTPUTFORMATTER( wxOutputStream& aStream, char aQuoteChar = '"' ) :
  326. os( aStream )
  327. {
  328. quoteChar[0] = aQuoteChar;
  329. quoteChar[1] = 0;
  330. }
  331. //-----<OUTPUTFORMATTER>------------------------------------------------
  332. const char* GetQuoteChar( const char* wrapee );
  333. protected:
  334. void write( const char* aOutBuf, int aCount ) throw( IOError );
  335. //-----</OUTPUTFORMATTER>-----------------------------------------------
  336. };
  337. #endif // RICHIO_H_