From 5b2248fad8423d8756c78277d159790bdc6f64e1 Mon Sep 17 00:00:00 2001 From: Seth Hillbrand Date: Thu, 28 Sep 2017 15:38:36 -0700 Subject: [PATCH] gerbview: Corrects handling of %FSD statement --- gerbview/class_X2_gerber_attributes.cpp | 4 +- gerbview/class_X2_gerber_attributes.h | 3 +- gerbview/class_gerber_file_image.cpp | 2 +- gerbview/class_gerber_file_image.h | 17 ++++++- gerbview/excellon_read_drill_file.cpp | 3 +- gerbview/job_file_reader.cpp | 3 -- gerbview/readgerb.cpp | 1 + gerbview/rs274_read_XY_and_IJ_coordinates.cpp | 2 +- gerbview/rs274d.cpp | 2 +- gerbview/rs274x.cpp | 49 ++++++++----------- 10 files changed, 47 insertions(+), 39 deletions(-) diff --git a/gerbview/class_X2_gerber_attributes.cpp b/gerbview/class_X2_gerber_attributes.cpp index fef61ede45..09c3a290fe 100644 --- a/gerbview/class_X2_gerber_attributes.cpp +++ b/gerbview/class_X2_gerber_attributes.cpp @@ -95,7 +95,8 @@ void X2_ATTRIBUTE::DbgListPrms() * buff = the buffer containing current Gerber data (GERBER_BUFZ size) * text = a pointer to the first char to read in Gerber data */ -bool X2_ATTRIBUTE::ParseAttribCmd( FILE* aFile, char *aBuffer, int aBuffSize, char* &aText ) +bool X2_ATTRIBUTE::ParseAttribCmd( FILE* aFile, char *aBuffer, int aBuffSize, char* &aText, + int& aLineNum ) { bool ok = true; wxString data; @@ -144,6 +145,7 @@ bool X2_ATTRIBUTE::ParseAttribCmd( FILE* aFile, char *aBuffer, int aBuffSize, ch break; } + aLineNum++; aText = aBuffer; } else diff --git a/gerbview/class_X2_gerber_attributes.h b/gerbview/class_X2_gerber_attributes.h index 25b2a8e8bd..4f43971c0d 100644 --- a/gerbview/class_X2_gerber_attributes.h +++ b/gerbview/class_X2_gerber_attributes.h @@ -96,9 +96,10 @@ public: * @param aText = a pointer to the first char to read from Gerber data stored in aBuffer * After parsing, text points the last char of the command line ('%') (X2 mode) * or the end of line if the line does not contain '%' or aBuffer == NULL (X1 mode) + * @oaram aLineNum = a point to the current line number of aFile * @return true if no error. */ - bool ParseAttribCmd( FILE* aFile, char *aBuffer, int aBuffSize, char* &aText ); + bool ParseAttribCmd( FILE* aFile, char *aBuffer, int aBuffSize, char* &aText, int& aLineNum ); /** * Debug function: pring using wxLogMessage le list of parameters diff --git a/gerbview/class_gerber_file_image.cpp b/gerbview/class_gerber_file_image.cpp index 0e35991ae7..4d2b18b0b4 100644 --- a/gerbview/class_gerber_file_image.cpp +++ b/gerbview/class_gerber_file_image.cpp @@ -195,7 +195,6 @@ void GERBER_FILE_IMAGE::ResetDefaultValues() m_Relative = false; // false = absolute Coord, // true = relative Coord m_NoTrailingZeros = false; // true: trailing zeros deleted - m_DecimalFormat = false; // true: use floating point notations for coordinates m_ImageOffset.x = m_ImageOffset.y = 0; // Coord Offset, from IO command m_ImageRotation = 0; // Allowed 0, 90, 180, 270 (in degree) m_LocalRotation = 0.0; // Layer totation from RO command (in 0.1 degree) @@ -220,6 +219,7 @@ void GERBER_FILE_IMAGE::ResetDefaultValues() m_PreviousPos.x = m_PreviousPos.y = 0; // last specified coord m_IJPos.x = m_IJPos.y = 0; // current centre coord for // plot arcs & circles + m_LineNum = 0; // line number in file being read m_Current_File = NULL; // Gerber file to read m_PolygonFillMode = false; m_PolygonFillModeState = 0; diff --git a/gerbview/class_gerber_file_image.h b/gerbview/class_gerber_file_image.h index 6d83ae91c5..a0f4798e3d 100644 --- a/gerbview/class_gerber_file_image.h +++ b/gerbview/class_gerber_file_image.h @@ -125,8 +125,6 @@ public: bool m_GerbMetric; // false = Inches, true = metric bool m_Relative; // false = absolute Coord, true = relative Coord bool m_NoTrailingZeros; // true: remove tailing zeros. - bool m_DecimalFormat; // true: use floating point notations for coordinates - // If true, overrides m_NoTrailingZeros parameter. wxPoint m_ImageOffset; // Coord Offset, from IO command wxSize m_FmtScale; // Fmt 2.3: m_FmtScale = 3, fmt 3.4: m_FmtScale = 4 wxSize m_FmtLen; // Nb chars per coord. ex fmt 2.3, m_FmtLen = 5 @@ -143,6 +141,7 @@ public: int m_Current_Tool; // Current Tool (Dcode) number selected int m_Last_Pen_Command; // Current or last pen state (0..9, set by Dn option with n <10 int m_CommandState; // state of gerber analysis command. + int m_LineNum; // Line number of the gerber file while reading wxPoint m_CurrentPos; // current specified coord for plot wxPoint m_PreviousPos; // old current specified coord for plot wxPoint m_IJPos; // IJ coord (for arcs & circles ) @@ -175,6 +174,20 @@ private: // -1 = negative items are // 0 = no negative items found // 1 = have negative items found + /** + * Function GetNextLine + * test for an end of line + * if an end of line is found: + * read a new line + * @param aBuff = buffer (size = GERBER_BUFZ) to fill with a new line + * @param aText = pointer to the last useful char in aBuff + * on return: points the beginning of the next line. + * @param aFile = the opened GERBER file to read + * @return a pointer to the beginning of the next line or NULL if end of file + */ + char* GetNextLine( char *aBuff, char* aText, FILE* aFile ); + + bool GetEndOfBlock( char* buff, char*& text, FILE* gerber_file ); public: GERBER_FILE_IMAGE( int layer ); diff --git a/gerbview/excellon_read_drill_file.cpp b/gerbview/excellon_read_drill_file.cpp index 6f949b6e21..950a10a7d7 100644 --- a/gerbview/excellon_read_drill_file.cpp +++ b/gerbview/excellon_read_drill_file.cpp @@ -307,7 +307,8 @@ bool EXCELLON_IMAGE::LoadFile( const wxString & aFullFileName ) // Add our file attribute, to identify the drill file X2_ATTRIBUTE dummy; char* text = (char*)file_attribute; - dummy.ParseAttribCmd( m_Current_File, NULL, 0, text ); + int dummyline = 0; + dummy.ParseAttribCmd( m_Current_File, NULL, 0, text, dummyline ); delete m_FileFunction; m_FileFunction = new X2_ATTRIBUTE_FILEFUNCTION( dummy ); diff --git a/gerbview/job_file_reader.cpp b/gerbview/job_file_reader.cpp index faf731d192..d4741ad330 100644 --- a/gerbview/job_file_reader.cpp +++ b/gerbview/job_file_reader.cpp @@ -39,9 +39,6 @@ #include #include -extern int ReadInt( char*& text, bool aSkipSeparator = true ); -extern double ReadDouble( char*& text, bool aSkipSeparator = true ); -extern bool GetEndOfBlock( char* buff, char*& text, FILE* gerber_file ); /** * this class read and parse a Gerber job file to extract useful info diff --git a/gerbview/readgerb.cpp b/gerbview/readgerb.cpp index f55c10f743..031711efa1 100644 --- a/gerbview/readgerb.cpp +++ b/gerbview/readgerb.cpp @@ -128,6 +128,7 @@ bool GERBER_FILE_IMAGE::LoadGerberFile( const wxString& aFullFileName ) if( fgets( line, sizeof(line), m_Current_File ) == NULL ) break; + m_LineNum++; text = StrPurge( line ); while( text && *text ) diff --git a/gerbview/rs274_read_XY_and_IJ_coordinates.cpp b/gerbview/rs274_read_XY_and_IJ_coordinates.cpp index c92cd63e9c..8e6289b6b5 100644 --- a/gerbview/rs274_read_XY_and_IJ_coordinates.cpp +++ b/gerbview/rs274_read_XY_and_IJ_coordinates.cpp @@ -73,7 +73,7 @@ wxPoint GERBER_FILE_IMAGE::ReadXYCoord( char*& Text ) { wxPoint pos; int type_coord = 0, current_coord, nbdigits; - bool is_float = m_DecimalFormat; + bool is_float = false; char* text; char line[256]; diff --git a/gerbview/rs274d.cpp b/gerbview/rs274d.cpp index 3d66bf8fea..8b79c92f39 100644 --- a/gerbview/rs274d.cpp +++ b/gerbview/rs274d.cpp @@ -484,7 +484,7 @@ bool GERBER_FILE_IMAGE::Execute_G_Command( char*& text, int G_command ) { text += 7; X2_ATTRIBUTE dummy; - dummy.ParseAttribCmd( m_Current_File, NULL, 0, text ); + dummy.ParseAttribCmd( m_Current_File, NULL, 0, text, m_LineNum ); if( dummy.IsFileFunction() ) { delete m_FileFunction; diff --git a/gerbview/rs274x.cpp b/gerbview/rs274x.cpp index fca35208b9..37c236c6e3 100644 --- a/gerbview/rs274x.cpp +++ b/gerbview/rs274x.cpp @@ -37,7 +37,6 @@ extern int ReadInt( char*& text, bool aSkipSeparator = true ); extern double ReadDouble( char*& text, bool aSkipSeparator = true ); -extern bool GetEndOfBlock( char* buff, char*& text, FILE* gerber_file ); #define CODE( x, y ) ( ( (x) << 8 ) + (y) ) @@ -233,7 +232,7 @@ bool GERBER_FILE_IMAGE::ReadRS274XCommand( char* buff, char*& text ) ok = false; break; } - + m_LineNum++; text = buff; } @@ -273,14 +272,21 @@ bool GERBER_FILE_IMAGE::ExecuteRS274XCommand( int command, char* buff, char*& te text++; break; + case 'D': // Non-standard option for all zeros (leading + tailing) + msg.Printf( _( "RS274X: Invalid GERBER format command '%c' at line %d: \"%s\"" ), + 'D', m_LineNum, buff ); + AddMessageToList( msg ); + msg.Printf( _("GERBER file \"%s\" may not display as intended." ), + m_FileName.ToAscii() ); + AddMessageToList( msg ); + // Fallthrough + case 'L': // No Leading 0 - m_DecimalFormat = false; m_NoTrailingZeros = false; text++; break; case 'T': // No trailing 0 - m_DecimalFormat = false; m_NoTrailingZeros = true; text++; break; @@ -305,16 +311,12 @@ bool GERBER_FILE_IMAGE::ExecuteRS274XCommand( int command, char* buff, char*& te seq_len = seq_char - '0'; break; - case 'D': case 'M': // Sequence code (followed by one digit: the sequence len) // (sometimes found after the X,Y sequence) // Obscure option code = *text++; if( ( *text >= '0' ) && ( *text<= '9' ) ) text++; // skip the digit - else if( code == 'D' ) - // Decimal format: sometimes found, but not really documented - m_DecimalFormat = true; break; case 'X': @@ -411,7 +413,7 @@ bool GERBER_FILE_IMAGE::ExecuteRS274XCommand( int command, char* buff, char*& te m_IsX2_file = true; { X2_ATTRIBUTE dummy; - dummy.ParseAttribCmd( m_Current_File, buff, GERBER_BUFZ, text ); + dummy.ParseAttribCmd( m_Current_File, buff, GERBER_BUFZ, text, m_LineNum ); if( dummy.IsFileFunction() ) { @@ -432,7 +434,7 @@ bool GERBER_FILE_IMAGE::ExecuteRS274XCommand( int command, char* buff, char*& te case APERTURE_ATTRIBUTE: // Command %TA ... Not yet supported { X2_ATTRIBUTE dummy; - dummy.ParseAttribCmd( m_Current_File, buff, GERBER_BUFZ, text ); + dummy.ParseAttribCmd( m_Current_File, buff, GERBER_BUFZ, text, m_LineNum ); if( dummy.GetAttribute() == ".AperFunction" ) { @@ -449,7 +451,7 @@ bool GERBER_FILE_IMAGE::ExecuteRS274XCommand( int command, char* buff, char*& te { X2_ATTRIBUTE dummy; - dummy.ParseAttribCmd( m_Current_File, buff, GERBER_BUFZ, text ); + dummy.ParseAttribCmd( m_Current_File, buff, GERBER_BUFZ, text, m_LineNum ); if( dummy.GetAttribute() == ".N" ) { @@ -473,7 +475,7 @@ bool GERBER_FILE_IMAGE::ExecuteRS274XCommand( int command, char* buff, char*& te case REMOVE_APERTURE_ATTRIBUTE: // Command %TD ... { X2_ATTRIBUTE dummy; - dummy.ParseAttribCmd( m_Current_File, buff, GERBER_BUFZ, text ); + dummy.ParseAttribCmd( m_Current_File, buff, GERBER_BUFZ, text, m_LineNum ); RemoveAttribute( dummy ); } break; @@ -902,7 +904,7 @@ bool GERBER_FILE_IMAGE::ExecuteRS274XCommand( int command, char* buff, char*& te } -bool GetEndOfBlock( char* buff, char*& text, FILE* gerber_file ) +bool GERBER_FILE_IMAGE::GetEndOfBlock( char* buff, char*& text, FILE* gerber_file ) { for( ; ; ) { @@ -920,6 +922,7 @@ bool GetEndOfBlock( char* buff, char*& text, FILE* gerber_file ) if( fgets( buff, GERBER_BUFZ, gerber_file ) == NULL ) break; + m_LineNum++; text = buff; } @@ -927,18 +930,7 @@ bool GetEndOfBlock( char* buff, char*& text, FILE* gerber_file ) } -/** - * Function GetNextLine - * test for an end of line - * if an end of line is found: - * read a new line - * @param aBuff = buffer (size = GERBER_BUFZ) to fill with a new line - * @param aText = pointer to the last useful char in aBuff - * on return: points the beginning of the next line. - * @param aFile = the opened GERBER file to read - * @return a pointer to the beginning of the next line or NULL if end of file -*/ -static char* GetNextLine( char *aBuff, char* aText, FILE* aFile ) +char* GERBER_FILE_IMAGE::GetNextLine( char *aBuff, char* aText, FILE* aFile ) { for( ; ; ) { @@ -953,6 +945,8 @@ static char* GetNextLine( char *aBuff, char* aText, FILE* aFile ) case 0: // End of text found in aBuff: Read a new string if( fgets( aBuff, GERBER_BUFZ, aFile ) == NULL ) return NULL; + + m_LineNum++; aText = aBuff; return aText; @@ -1078,9 +1072,8 @@ bool GERBER_FILE_IMAGE::ReadApertureMacro( char *buff, break; default: - // @todo, there needs to be a way of reporting the line number - msg.Printf( wxT( "RS274X: Aperture Macro \"%s\": Invalid primitive id code %d, line: \"%s\"" ), - GetChars( am.name ), primitive_type, GetChars( FROM_UTF8( buff ) ) ); + msg.Printf( wxT( "RS274X: Aperture Macro \"%s\": Invalid primitive id code %d, line %d: \"%s\"" ), + GetChars( am.name ), primitive_type, m_LineNum, GetChars( FROM_UTF8( buff ) ) ); AddMessageToList( msg ); return false; }