← Back to team overview

kicad-developers team mailing list archive

Re: IDF Export bug

 

Please try the attached patch. The issue may be with std::getline() and the
variations
in \r, \n at the end of a text line. If that is the case then this patch
should fix it. If
the problem persists then I need to look more carefully into the issue (it
will likely
be a defective implementation of the seek/tell functions).

- Cirilo

On Sat, Jan 10, 2015 at 1:45 AM, Chris Anon <chris.aa05@xxxxxxxxx> wrote:

> I'm using winXP at work. I'll try on my Ubuntu system at home this
> weekend. idf2vrml produces:
>
> ** Failed to read IDF data:
> * C:\KiCadBuild\src\kicad\utils\idftools\idf_outlines.cpp:1206:readData():
> * invalid outline: .BOARD_OUTLINE
> * violation: no .END_BOARD_OUTLINE found
> * file position: 282
>
> with the attached file.
>
> On Thu, Jan 8, 2015 at 3:30 PM, Cirilo Bernardo <cirilo.bernardo@xxxxxxxxx
> > wrote:
>
>> On Fri, Jan 9, 2015 at 4:52 AM, Chris Anon <chris.aa05@xxxxxxxxx> wrote:
>>
>>> Trying to export with the included file for an 0805 capacitor produces
>>> error:
>>>
>>> *invalid outline: COMPONENT OUTLINE
>>> *violation: expecting PROP or .END_ELECTRICAL
>>> *line: 'END_ELECTRICAL'
>>>  If I add a space before '.END_ELECTRICAL' in the file there's no error.
>>>
>>> On Wed, Jan 7, 2015 at 4:10 PM, Cirilo Bernardo <
>>> cirilo.bernardo@xxxxxxxxx> wrote:
>>>
>>>> On Thu, Jan 8, 2015 at 1:22 AM, Chris Anon <chris.aa05@xxxxxxxxx>
>>>> wrote:
>>>>
>>>>> Hey all, I've been using Kicad for several years now and I've finally
>>>>> gotten around to pulling the source and building it myself. The latest
>>>>> developments look really exciting. Anyway, I think I've found a few bugs in
>>>>> the IDF export code. I currently have version 2014-12-16 BZR 5324. When
>>>>> storing IDF files for components in a path specified by the KISYS3DMOD
>>>>> environment variable, the exporter can't find the idf files. Changing '
>>>>> GetShape3DName' to 'GetShape3DFullFilename' in line 370 of
>>>>> 'export_idf.cpp' function 'idf_export_module' seems to fix this. I also
>>>>> noticed that the parser function seems to be stripping off the '.' in
>>>>> '.END_ELECTRICAL' at the end of a component idf file. adding a space before
>>>>> '.END_ELECTRICAL' fixes this but I haven't dug deep enough into the code to
>>>>> find out why this happens in the first place.
>>>>>
>>>>>
>>>> Hi Chris,
>>>>
>>>>  I can't confirm your report about the parser eating the '.' in
>>>> '.END_ELECTRICAL'.
>>>> Do you have anything which shows this problem?
>>>>
>>>> - Cirilo
>>>>
>>>
>>>
>> Hi Chris,
>>
>>  Your IDF file works fine on my system. Can you try the 'idf2vrml' tool
>> on the exported files
>> to check if the '.' also disappears there? What operating system are you
>> using?
>>
>> - Cirilo
>>
>>
>
=== modified file 'pcbnew/exporters/export_idf.cpp'
--- pcbnew/exporters/export_idf.cpp	2015-01-05 21:51:47 +0000
+++ pcbnew/exporters/export_idf.cpp	2015-01-07 20:52:07 +0000
@@ -378,7 +378,7 @@
 
         IDF3_COMP_OUTLINE* outline;
 
-        outline = aIDFBoard.GetComponentOutline( modfile->GetShape3DName() );
+        outline = aIDFBoard.GetComponentOutline( modfile->GetShape3DFullFilename() );
 
         if( !outline )
             throw( std::runtime_error( aIDFBoard.GetError() ) );

=== modified file 'utils/idftools/idf_helpers.cpp'
--- utils/idftools/idf_helpers.cpp	2014-06-01 16:55:53 +0000
+++ utils/idftools/idf_helpers.cpp	2015-01-09 23:51:04 +0000
@@ -31,6 +31,49 @@
 using namespace std;
 using namespace IDF3;
 
+static void Getline(std::istream& aIStream, std::string& aString)
+{
+    aString.clear();
+
+    std::istream::sentry s(aIStream, true);
+    std::streambuf* sbuf = aIStream.rdbuf();
+
+    int c;
+    bool end = false;
+
+    while(!end)
+    {
+        c = sbuf->sbumpc();
+
+        switch( c )
+        {
+        case '\n':
+            end = true;
+            break;
+
+        case '\r':
+            if(sbuf->sgetc() == '\n')
+                sbuf->sbumpc();
+
+            end = true;
+            break;
+
+        case EOF:
+            if(aString.empty())
+                aIStream.setstate(std::ios::eofbit);
+
+            end = true;
+            break;
+
+        default:
+            aString += (char)c;
+            break;
+        }
+    }
+
+    return;
+}
+
 // fetch a line from the given input file and trim the ends
 bool IDF3::FetchIDFLine( std::ifstream& aModel, std::string& aLine, bool& isComment, std::streampos& aFilePos )
 {
@@ -40,7 +83,7 @@
     if( aFilePos == -1 )
         return false;
 
-    std::getline( aModel, aLine );
+    Getline( aModel, aLine );
 
     isComment = false;
 


Follow ups

References