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.

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