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.

548 lines
18 KiB

15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
16 years ago
16 years ago
16 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 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) 2016 KiCad Developers, see AUTHORS.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 <vector>
  29. #include <utf8.h>
  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 <cstdio>
  33. #include <wx/wx.h>
  34. #include <ki_exception.h>
  35. /**
  36. * Function StrPrintf
  37. * is like sprintf() but the output is appended to a std::string instead of to a
  38. * character array.
  39. * @param aResult is the string to append to, previous text is not clear()ed.
  40. * @param aFormat is a printf() style format string.
  41. * @return int - the count of bytes appended to the result string, no terminating
  42. * nul is included.
  43. */
  44. int
  45. #if defined(__GNUG__)
  46. __attribute__ ((format (printf, 2, 3)))
  47. #endif
  48. StrPrintf( std::string* aResult, const char* aFormat, ... );
  49. /**
  50. * Function StrPrintf
  51. * is like sprintf() but the output is returned in a std::string instead of to a
  52. * character array.
  53. * @param format is a printf() style format string.
  54. * @return std::string - the result of the sprintf().
  55. */
  56. std::string
  57. #if defined(__GNUG__)
  58. __attribute__ ((format (printf, 1, 2)))
  59. #endif
  60. StrPrintf( const char* format, ... );
  61. #define LINE_READER_LINE_DEFAULT_MAX 1000000
  62. #define LINE_READER_LINE_INITIAL_SIZE 5000
  63. /**
  64. * LINE_READER
  65. * is an abstract class from which implementation specific LINE_READERs may
  66. * be derived to read single lines of text and manage a line number counter.
  67. */
  68. class LINE_READER
  69. {
  70. protected:
  71. unsigned m_length; ///< no. bytes in line before trailing nul.
  72. unsigned m_lineNum;
  73. char* m_line; ///< the read line of UTF8 text
  74. unsigned m_capacity; ///< no. bytes allocated for line.
  75. unsigned m_maxLineLength; ///< maximum allowed capacity using resizing.
  76. wxString m_source; ///< origin of text lines, e.g. filename or "clipboard"
  77. /**
  78. * Function expandCapacity
  79. * will expand the capacity of @a line up to maxLineLength but not greater, so
  80. * be careful about making assumptions of @a capacity after calling this.
  81. */
  82. void expandCapacity( unsigned aNewsize );
  83. public:
  84. /**
  85. * Constructor LINE_READER
  86. * builds a line reader and fixes the length of the maximum supported
  87. * line length to @a aMaxLineLength.
  88. */
  89. LINE_READER( unsigned aMaxLineLength = LINE_READER_LINE_DEFAULT_MAX );
  90. virtual ~LINE_READER();
  91. /**
  92. * Function ReadLine
  93. * reads a line of text into the buffer and increments the line number
  94. * counter. If the line is larger than aMaxLineLength passed to the
  95. * constructor, then an exception is thrown. The line is nul terminated.
  96. * @return char* - The beginning of the read line, or NULL if EOF.
  97. * @throw IO_ERROR when a line is too long.
  98. */
  99. virtual char* ReadLine() = 0;
  100. /**
  101. * Function GetSource
  102. * returns the name of the source of the lines in an abstract sense.
  103. * This may be a file or it may be the clipboard or any other source
  104. * of lines of text. The returned string is useful for reporting error
  105. * messages.
  106. */
  107. virtual const wxString& GetSource() const
  108. {
  109. return m_source;
  110. }
  111. /**
  112. * Function Line
  113. * returns a pointer to the last line that was read in.
  114. */
  115. char* Line() const
  116. {
  117. return m_line;
  118. }
  119. /**
  120. * Operator char*
  121. * is a casting operator that returns a char* pointer to the start of the
  122. * line buffer.
  123. */
  124. operator char* () const
  125. {
  126. return Line();
  127. }
  128. /**
  129. * Function Line Number
  130. * returns the line number of the last line read from this LINE_READER. Lines
  131. * start from 1.
  132. */
  133. virtual unsigned LineNumber() const
  134. {
  135. return m_lineNum;
  136. }
  137. /**
  138. * Function Length
  139. * returns the number of bytes in the last line read from this LINE_READER.
  140. */
  141. unsigned Length() const
  142. {
  143. return m_length;
  144. }
  145. };
  146. /**
  147. * FILE_LINE_READER
  148. * is a LINE_READER that reads from an open file. File must be already open
  149. * so that this class can exist without any UI policy.
  150. */
  151. class FILE_LINE_READER : public LINE_READER
  152. {
  153. protected:
  154. bool m_iOwn; ///< if I own the file, I'll promise to close it, else not.
  155. FILE* m_fp; ///< I may own this file, but might not.
  156. public:
  157. /**
  158. * Constructor FILE_LINE_READER
  159. * takes @a aFileName and the size of the desired line buffer and opens
  160. * the file and assumes the obligation to close it.
  161. *
  162. * @param aFileName is the name of the file to open and to use for error reporting purposes.
  163. *
  164. * @param aStartingLineNumber is the initial line number to report on error, and is
  165. * accessible here for the case where multiple DSNLEXERs are reading from the
  166. * same file in sequence, all from the same open file (with @a doOwn = false).
  167. * Internally it is incremented by one after each ReadLine(), so the first
  168. * reported line number will always be one greater than what is provided here.
  169. *
  170. * @param aMaxLineLength is the number of bytes to use in the line buffer.
  171. *
  172. * @throw IO_ERROR if @a aFileName cannot be opened.
  173. */
  174. FILE_LINE_READER( const wxString& aFileName,
  175. unsigned aStartingLineNumber = 0,
  176. unsigned aMaxLineLength = LINE_READER_LINE_DEFAULT_MAX );
  177. /**
  178. * Constructor FILE_LINE_READER
  179. * takes an open FILE and the size of the desired line buffer and takes
  180. * ownership of the open file, i.e. assumes the obligation to close it.
  181. *
  182. * @param aFile is an open file.
  183. * @param aFileName is the name of the file for error reporting purposes.
  184. * @param doOwn if true, means I should close the open file, else not.
  185. * @param aStartingLineNumber is the initial line number to report on error, and is
  186. * accessible here for the case where multiple DSNLEXERs are reading from the
  187. * same file in sequence, all from the same open file (with @a doOwn = false).
  188. * Internally it is incremented by one after each ReadLine(), so the first
  189. * reported line number will always be one greater than what is provided here.
  190. * @param aMaxLineLength is the number of bytes to use in the line buffer.
  191. */
  192. FILE_LINE_READER( FILE* aFile, const wxString& aFileName, bool doOwn = true,
  193. unsigned aStartingLineNumber = 0,
  194. unsigned aMaxLineLength = LINE_READER_LINE_DEFAULT_MAX );
  195. /**
  196. * Destructor
  197. * may or may not close the open file, depending on @a doOwn in constructor.
  198. */
  199. ~FILE_LINE_READER();
  200. char* ReadLine() override;
  201. /**
  202. * Function Rewind
  203. * rewinds the file and resets the line number back to zero. Line number
  204. * will go to 1 on first ReadLine().
  205. */
  206. void Rewind()
  207. {
  208. rewind( m_fp );
  209. m_lineNum = 0;
  210. }
  211. };
  212. /**
  213. * STRING_LINE_READER
  214. * is a LINE_READER that reads from a multiline 8 bit wide std::string
  215. */
  216. class STRING_LINE_READER : public LINE_READER
  217. {
  218. protected:
  219. std::string m_lines;
  220. size_t m_ndx;
  221. public:
  222. /**
  223. * Constructor STRING_LINE_READER( const std::string&, const wxString& )
  224. *
  225. * @param aString is a source string consisting of one or more lines
  226. * of text, where multiple lines are separated with a '\n' character.
  227. * The last line does not necessarily need a trailing '\n'.
  228. *
  229. * @param aSource describes the source of aString for error reporting purposes
  230. * can be anything meaninful, such as wxT( "clipboard" ).
  231. */
  232. STRING_LINE_READER( const std::string& aString, const wxString& aSource );
  233. /**
  234. * Constructor STRING_LINE_READER( const STRING_LINE_READER& )
  235. * allows for a continuation of the reading of a stream started by another
  236. * STRING_LINE_READER. Any stream offset and source name are used from
  237. * @a aStartingPoint.
  238. */
  239. STRING_LINE_READER( const STRING_LINE_READER& aStartingPoint );
  240. char* ReadLine() override;
  241. };
  242. /**
  243. * INPUTSTREAM_LINE_READER
  244. * is a LINE_READER that reads from a wxInputStream object.
  245. */
  246. class INPUTSTREAM_LINE_READER : public LINE_READER
  247. {
  248. protected:
  249. wxInputStream* m_stream; //< The input stream to read. No ownership of this pointer.
  250. public:
  251. /**
  252. * Constructor WXINPUTSTREAM_LINE_READER
  253. *
  254. * @param aStream A pointer to a wxInputStream object to read.
  255. * @param aSource The name of the stream source, for error reporting purposes.
  256. */
  257. INPUTSTREAM_LINE_READER( wxInputStream* aStream, const wxString& aSource );
  258. char* ReadLine() override;
  259. };
  260. #define OUTPUTFMTBUFZ 500 ///< default buffer size for any OUTPUT_FORMATTER
  261. /**
  262. * OUTPUTFORMATTER
  263. * is an important interface (abstract class) used to output 8 bit text in
  264. * a convenient way. The primary interface is "printf() - like" but
  265. * with support for indentation control. The destination of the 8 bit
  266. * wide text is up to the implementer.
  267. * <p>
  268. * The implementer only has to implement the write() function, but can
  269. * also optionally re-implement GetQuoteChar().
  270. * <p>
  271. * If you want to output a wxString, then use TO_UTF8() on it
  272. * before passing it as an argument to Print().
  273. * <p>
  274. * Since this is an abstract interface, only classes derived from
  275. * this one may actually be used.
  276. */
  277. class OUTPUTFORMATTER
  278. {
  279. std::vector<char> m_buffer;
  280. char quoteChar[2];
  281. int sprint( const char* fmt, ... );
  282. int vprint( const char* fmt, va_list ap );
  283. protected:
  284. OUTPUTFORMATTER( int aReserve = OUTPUTFMTBUFZ, char aQuoteChar = '"' ) :
  285. m_buffer( aReserve, '\0' )
  286. {
  287. quoteChar[0] = aQuoteChar;
  288. quoteChar[1] = '\0';
  289. }
  290. virtual ~OUTPUTFORMATTER() {}
  291. /**
  292. * Function GetQuoteChar
  293. * performs quote character need determination according to the Specctra DSN
  294. * specification.
  295. * @param wrapee A string that might need wrapping on each end.
  296. * @param quote_char A single character C string which provides the current
  297. * quote character, should it be needed by the wrapee.
  298. *
  299. * @return const char* - the quote_char as a single character string, or ""
  300. * if the wrapee does not need to be wrapped.
  301. */
  302. static const char* GetQuoteChar( const char* wrapee, const char* quote_char );
  303. /**
  304. * Function write
  305. * should be coded in the interface implementation (derived) classes.
  306. *
  307. * @param aOutBuf is the start of a byte buffer to write.
  308. * @param aCount tells how many bytes to write.
  309. * @throw IO_ERROR, if there is a problem outputting, such as a full disk.
  310. */
  311. virtual void write( const char* aOutBuf, int aCount ) = 0;
  312. #if defined(__GNUG__) // The GNU C++ compiler defines this
  313. // When used on a C++ function, we must account for the "this" pointer,
  314. // so increase the STRING-INDEX and FIRST-TO_CHECK by one.
  315. // See http://docs.freebsd.org/info/gcc/gcc.info.Function_Attributes.html
  316. // Then to get format checking during the compile, compile with -Wall or -Wformat
  317. #define PRINTF_FUNC __attribute__ ((format (printf, 3, 4)))
  318. #else
  319. #define PRINTF_FUNC // nothing
  320. #endif
  321. public:
  322. //-----<interface functions>------------------------------------------
  323. /**
  324. * Function Print
  325. * formats and writes text to the output stream.
  326. *
  327. * @param nestLevel The multiple of spaces to precede the output with.
  328. * @param fmt A printf() style format string.
  329. * @param ... a variable list of parameters that will get blended into
  330. * the output under control of the format string.
  331. * @return int - the number of characters output.
  332. * @throw IO_ERROR, if there is a problem outputting, such as a full disk.
  333. */
  334. int PRINTF_FUNC Print( int nestLevel, const char* fmt, ... );
  335. /**
  336. * Function GetQuoteChar
  337. * performs quote character need determination.
  338. * It returns the quote character as a single character string for a given
  339. * input wrapee string. If the wrappee does not need to be quoted,
  340. * the return value is "" (the null string), such as when there are no
  341. * delimiters in the input wrapee string. If you want the quote_char
  342. * to be assuredly not "", then pass in "(" as the wrappee.
  343. * <p>
  344. * Implementations are free to override the default behavior, which is to
  345. * call the static function of the same name.
  346. * @param wrapee A string that might need wrapping on each end.
  347. * @return const char* - the quote_char as a single character string, or ""
  348. * if the wrapee does not need to be wrapped.
  349. */
  350. virtual const char* GetQuoteChar( const char* wrapee );
  351. /**
  352. * Function Quotes
  353. * checks \a aWrapee input string for a need to be quoted
  354. * (e.g. contains a ')' character or a space), and for \" double quotes
  355. * within the string that need to be escaped such that the DSNLEXER
  356. * will correctly parse the string from a file later.
  357. *
  358. * @param aWrapee is a string that might need wraping in double quotes,
  359. * and it might need to have its internal content escaped, or not.
  360. *
  361. * @return std::string - whose c_str() function can be called for passing
  362. * to printf() style functions that output UTF8 encoded s-expression streams.
  363. *
  364. * @throw IO_ERROR, if there is any kind of problem with the input string.
  365. */
  366. virtual std::string Quotes( const std::string& aWrapee );
  367. std::string Quotew( const wxString& aWrapee );
  368. //-----</interface functions>-----------------------------------------
  369. };
  370. /**
  371. * STRING_FORMATTER
  372. * implements OUTPUTFORMATTER to a memory buffer. After Print()ing the
  373. * string is available through GetString()
  374. */
  375. class STRING_FORMATTER : public OUTPUTFORMATTER
  376. {
  377. std::string m_mystring;
  378. public:
  379. /**
  380. * Constructor STRING_FORMATTER
  381. * reserves space in the buffer
  382. */
  383. STRING_FORMATTER( int aReserve = OUTPUTFMTBUFZ, char aQuoteChar = '"' ) :
  384. OUTPUTFORMATTER( aReserve, aQuoteChar )
  385. {
  386. }
  387. /**
  388. * Function Clear
  389. * clears the buffer and empties the internal string.
  390. */
  391. void Clear()
  392. {
  393. m_mystring.clear();
  394. }
  395. /**
  396. * Function StripUseless
  397. * removes whitespace, '(', and ')' from the mystring.
  398. */
  399. void StripUseless();
  400. const std::string& GetString()
  401. {
  402. return m_mystring;
  403. }
  404. protected:
  405. //-----<OUTPUTFORMATTER>------------------------------------------------
  406. void write( const char* aOutBuf, int aCount ) override;
  407. //-----</OUTPUTFORMATTER>-----------------------------------------------
  408. };
  409. /**
  410. * FILE_OUTPUTFORMATTER
  411. * may be used for text file output. It is about 8 times faster than
  412. * STREAM_OUTPUTFORMATTER for file streams.
  413. */
  414. class FILE_OUTPUTFORMATTER : public OUTPUTFORMATTER
  415. {
  416. public:
  417. /**
  418. * Constructor
  419. * @param aFileName is the full filename to open and save to as a text file.
  420. * @param aMode is what you would pass to wxFopen()'s mode, defaults to wxT( "wt" )
  421. * for text files that are to be created here and now.
  422. * @param aQuoteChar is a char used for quoting problematic strings
  423. (with whitespace or special characters in them).
  424. * @throw IO_ERROR if the file cannot be opened.
  425. */
  426. FILE_OUTPUTFORMATTER( const wxString& aFileName,
  427. const wxChar* aMode = wxT( "wt" ),
  428. char aQuoteChar = '"' );
  429. ~FILE_OUTPUTFORMATTER();
  430. protected:
  431. //-----<OUTPUTFORMATTER>------------------------------------------------
  432. void write( const char* aOutBuf, int aCount ) override;
  433. //-----</OUTPUTFORMATTER>-----------------------------------------------
  434. FILE* m_fp; ///< takes ownership
  435. wxString m_filename;
  436. };
  437. /**
  438. * STREAM_OUTPUTFORMATTER
  439. * implements OUTPUTFORMATTER to a wxWidgets wxOutputStream. The stream is
  440. * neither opened nor closed by this class.
  441. */
  442. class STREAM_OUTPUTFORMATTER : public OUTPUTFORMATTER
  443. {
  444. wxOutputStream& m_os;
  445. public:
  446. /**
  447. * Constructor STREAM_OUTPUTFORMATTER
  448. * can take any number of wxOutputStream derivations, so it can write
  449. * to a file, socket, or zip file.
  450. */
  451. STREAM_OUTPUTFORMATTER( wxOutputStream& aStream, char aQuoteChar = '"' ) :
  452. OUTPUTFORMATTER( OUTPUTFMTBUFZ, aQuoteChar ),
  453. m_os( aStream )
  454. {
  455. }
  456. protected:
  457. //-----<OUTPUTFORMATTER>------------------------------------------------
  458. void write( const char* aOutBuf, int aCount ) override;
  459. //-----</OUTPUTFORMATTER>-----------------------------------------------
  460. };
  461. #endif // RICHIO_H_