From 558af6d76407c9121f970da30fdb1c2943f0f996 Mon Sep 17 00:00:00 2001 From: Dick Hollenbeck Date: Sat, 26 Feb 2011 23:43:19 -0600 Subject: [PATCH] add EscapedUTF8() and revise ReadDelimitedText() to complement it --- common/string.cpp | 76 ++++++++++++++++++++++++++++++--------- include/kicad_string.h | 32 +++++++++++++---- new/toolchain-mingw.cmake | 2 +- pcbnew/class_pcb_text.cpp | 30 +++++++++------- pcbnew/ioascii.cpp | 6 ++-- 5 files changed, 104 insertions(+), 42 deletions(-) diff --git a/common/string.cpp b/common/string.cpp index 55a46b077c..cf07d307db 100644 --- a/common/string.cpp +++ b/common/string.cpp @@ -8,32 +8,74 @@ #include "kicad_string.h" -/* read a double-quote delimited text from source and put it in in dest, - * read NbMaxChar bytes max - * return the char count read from source - */ -int ReadDelimitedText( char* dest, char* source, int NbMaxChar ) +int ReadDelimitedText( char* aDest, const char* aSource, int aDestSize ) { - int ii, jj, flag = 0; + if( aDestSize <= 0 ) + return 0; - for( ii = 0, jj = 0; ii < NbMaxChar - 1; jj++, source++ ) + bool inside = false; + char* start = aDest; + char* limit = aDest + aDestSize - 1; + char cc; + + while( (cc = *aSource++) != 0 && aDest < limit ) { - if( *source == 0 ) - break; /* E.O.L. */ - if( *source == '"' ) /* delimiter is " */ + if( cc == '\\' ) { - if( flag ) - break; /* End of delimited text */ - flag = 1; /* First delimiter found. */ + cc = *aSource++; + + if( inside ) + *aDest++ = cc; } - else if( flag ) + + else if( cc == '"' ) { - *dest = *source; dest++; ii++; + if( inside ) + break; // 2nd double quote is end of delimited text + + inside = true; // first delimiter found, make note, do not copy + } + + else if( inside ) + { + *aDest++ = cc; } } - *dest = 0; /* Null terminated */ - return jj; + *aDest = 0; + + return aDest - start; +} + + +std::string EscapedUTF8( const wxString& aString ) +{ + std::string utf8 = TO_UTF8( aString ); + + std::string ret; + + // ret += '"'; + + for( std::string::const_iterator it = utf8.begin(); it!=utf8.end(); ++it ) + { + // this escaping strategy is designed to be compatible with ReadDelimitedText(): + if( *it == '"' ) + { + ret += '\\'; + ret += '"'; + } + else if( *it == '\\' ) + { + ret += '\\'; // double it up + ret += '\\'; + } + else + ret += *it; + } + + // ret += '"'; + + return ret; } diff --git a/include/kicad_string.h b/include/kicad_string.h index 37df8665bb..8b11a111a6 100644 --- a/include/kicad_string.h +++ b/include/kicad_string.h @@ -14,14 +14,32 @@ char* strupper( char* Text ); char* strlower( char* Text ); -/* Read string delimited with (") character. - * Upload NbMaxChar max - * Returns the number of codes read in source - * dest is terminated by NULL + +/** + * Function ReadDelimitedText + * extracts bytes from @a aSource delimited string segment to @a aDest buffer. + * The extracted string will be null terminated even if truncation is necessary + * because aDestSize was not large enough. + * + * @param aDest is the destination byte buffer. + * @param aSource is the source bytes as a C string. + * @param aDestSize is the size of the destination byte buffer. + * @return int - the number of bytes extracted. */ -int ReadDelimitedText( char* dest, - char* source, - int NbMaxChar ); +int ReadDelimitedText( char* aDest, const char* aSource, int aDestSize ); + + +/** + * Function EscapedUTF8 + * returns an 8 bit UTF8 string given aString in unicode form. + * Any double quoted or back slashes are prefixed with a '\\' byte and the form + * of this UTF8 byte string is compatible with function ReadDelimitedText(). + * + * @param aString is the input string to convert. + * @return std::string - the escaped input text, without the wrapping double quotes. + */ +std::string EscapedUTF8( const wxString& aString ); + /* Read one line line from a file. * Returns the first useful line read by eliminating blank lines and comments. diff --git a/new/toolchain-mingw.cmake b/new/toolchain-mingw.cmake index 38ef757654..387188aff5 100644 --- a/new/toolchain-mingw.cmake +++ b/new/toolchain-mingw.cmake @@ -7,7 +7,7 @@ # It is here to assist Dick with verifying compilation of /new stuff with mingw (under linux) -set( CMAKE_SYSTEM_NAME Linux ) +set( CMAKE_SYSTEM_NAME Windows ) #---------------------------------------------------- diff --git a/pcbnew/class_pcb_text.cpp b/pcbnew/class_pcb_text.cpp index 6e2760da79..ef7a692179 100644 --- a/pcbnew/class_pcb_text.cpp +++ b/pcbnew/class_pcb_text.cpp @@ -80,31 +80,31 @@ void TEXTE_PCB::Copy( TEXTE_PCB* source ) */ int TEXTE_PCB::ReadTextePcbDescr( LINE_READER* aReader ) { - char* Line; + char* line; char text[1024]; char style[256]; while( aReader->ReadLine() ) { - Line = aReader->Line(); - if( strnicmp( Line, "$EndTEXTPCB", 11 ) == 0 ) + line = aReader->Line(); + if( strnicmp( line, "$EndTEXTPCB", 11 ) == 0 ) return 0; - if( strncmp( Line, "Te", 2 ) == 0 ) /* Text line (first line for multi line texts */ + if( strncmp( line, "Te", 2 ) == 0 ) /* Text line (first line for multi line texts */ { - ReadDelimitedText( text, Line + 2, sizeof(text) ); + ReadDelimitedText( text, line + 2, sizeof(text) ); m_Text = CONV_FROM_UTF8( text ); continue; } - if( strncmp( Line, "nl", 2 ) == 0 ) /* next line of the current text */ + if( strncmp( line, "nl", 2 ) == 0 ) /* next line of the current text */ { - ReadDelimitedText( text, Line + 2, sizeof(text) ); + ReadDelimitedText( text, line + 2, sizeof(text) ); m_Text.Append( '\n' ); m_Text += CONV_FROM_UTF8( text ); continue; } - if( strncmp( Line, "Po", 2 ) == 0 ) + if( strncmp( line, "Po", 2 ) == 0 ) { - sscanf( Line + 2, " %d %d %d %d %d %d", + sscanf( line + 2, " %d %d %d %d %d %d", &m_Pos.x, &m_Pos.y, &m_Size.x, &m_Size.y, &m_Thickness, &m_Orient ); @@ -115,11 +115,11 @@ int TEXTE_PCB::ReadTextePcbDescr( LINE_READER* aReader ) m_Size.y = 5; continue; } - if( strncmp( Line, "De", 2 ) == 0 ) + if( strncmp( line, "De", 2 ) == 0 ) { style[0] = 0; int normal_display = 1; - sscanf( Line + 2, " %d %d %lX %s\n", &m_Layer, &normal_display, + sscanf( line + 2, " %d %d %lX %s\n", &m_Layer, &normal_display, &m_TimeStamp, style ); m_Mirror = normal_display ? false : true; @@ -157,18 +157,22 @@ bool TEXTE_PCB::Save( FILE* aFile ) const const char* style = m_Italic ? "Italic" : "Normal"; wxArrayString* list = wxStringSplit( m_Text, '\n' ); + for( unsigned ii = 0; ii < list->Count(); ii++ ) { wxString txt = list->Item( ii ); + if ( ii == 0 ) - fprintf( aFile, "Te \"%s\"\n", CONV_TO_UTF8( txt ) ); + fprintf( aFile, "Te \"%s\"\n", EscapedUTF8( txt ).c_str() ); else fprintf( aFile, "nl \"%s\"\n", CONV_TO_UTF8( txt ) ); } - delete (list); + + delete list; fprintf( aFile, "Po %d %d %d %d %d %d\n", m_Pos.x, m_Pos.y, m_Size.x, m_Size.y, m_Thickness, m_Orient ); + fprintf( aFile, "De %d %d %lX %s\n", m_Layer, m_Mirror ? 0 : 1, m_TimeStamp, style ); diff --git a/pcbnew/ioascii.cpp b/pcbnew/ioascii.cpp index 92154c9ad9..a315460cf1 100644 --- a/pcbnew/ioascii.cpp +++ b/pcbnew/ioascii.cpp @@ -327,13 +327,11 @@ int WinEDA_BasePcbFrame::ReadSetup( LINE_READER* aReader ) } catch( IO_ERROR& e ) { -#if 1 wxString msg; - msg.Printf( wxT( "Error reading PcbPlotParams from %s:\n%s" ), + msg.Printf( _( "Error reading PcbPlotParams from %s:\n%s" ), aReader->GetSource().GetData(), e.errorText.GetData() ); - wxMessageBox( msg, wxT( "Open Board File" ), wxICON_ERROR ); -#endif + wxMessageBox( msg, _( "Open Board File" ), wxICON_ERROR ); } continue;