Gerber job file: fix incorrect GUID.

Fixes: lp:1801696
https://bugs.launchpad.net/kicad/+bug/1801696
This commit is contained in:
jean-pierre charras 2018-11-06 08:16:07 +01:00
parent 922ce89643
commit 839ade2c05
4 changed files with 91 additions and 101 deletions

View File

@ -32,6 +32,80 @@
#include <gbr_metadata.h>
wxString GbrMakeProjectGUIDfromString( wxString& aText )
{
/* Gerber GUID format should be RFC4122 Version 1 or 4.
* See en.wikipedia.org/wiki/Universally_unique_identifier
* The format is:
* xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
* with
* x = hexDigit lower/upper case
* and
* M = '1' or '4' (UUID version: 1 (basic) or 4 (random)) (we use 4: UUID random)
* and
* N = '8' or '9' or 'A|a' or 'B|b' : UUID variant 1: 2 MSB bits have meaning) (we use N = 9)
* N = 1000 or 1001 or 1010 or 1011 : 10xx means Variant 1 (Variant2: 110x and 111x are reserved)
*/
wxString guid;
// Build a 32 digits GUID from the board name:
// guid has 32 digits, so add chars in name to be sure we can build a 32 digits guid
// (i.e. from a 16 char string name)
// In fact only 30 digits are used, and 2 UID id
wxString bname = aText;
int cnt = 16 - bname.Len();
if( cnt > 0 )
bname.Append( 'X', cnt );
int chr_idx = 0;
// Output the 8 first hex digits:
for( unsigned ii = 0; ii < 4; ii++ )
{
int cc = int( bname[chr_idx++] ) & 0xFF;
guid << wxString::Format( "%2.2x", cc );
}
// Output the 4 next hex digits:
guid << '-';
for( unsigned ii = 0; ii < 2; ii++ )
{
int cc = int( bname[chr_idx++] ) & 0xFF;
guid << wxString::Format( "%2.2x", cc );
}
// Output the 4 next hex digits (UUID version and 3 digits):
guid << "-4"; // first digit: UUID version 4 (M = 4)
{
int cc = int( bname[chr_idx++] ) << 4 & 0xFF0;
cc += int( bname[chr_idx] ) >> 4 & 0x0F;
guid << wxString::Format( "%3.3x", cc );
}
// Output the 4 next hex digits (UUID variant and 3 digits):
guid << "-9"; // first digit: UUID variant 1 (N = 9)
{
int cc = (int( bname[chr_idx++] ) & 0x0F) << 8;
cc += int( bname[chr_idx++] ) & 0xFF;
guid << wxString::Format( "%3.3x", cc );
}
// Output the 12 last hex digits:
guid << '-';
for( unsigned ii = 0; ii < 6; ii++ )
{
int cc = int( bname[chr_idx++] ) & 0xFF;
guid << wxString::Format( "%2.2x", cc );
}
return guid;
}
std::string GBR_APERTURE_METADATA::FormatAttribute( GBR_APERTURE_ATTRIB aAttribute,
bool aUseX1StructuredComment )
{

View File

@ -35,6 +35,16 @@
#include <gbr_netlist_metadata.h>
/** A helper function to build a project GUID using format RFC4122 Version 1 or 4
* from the project name, because a kicad project has no specific GUID
* RFC4122 is used mainly for its syntax, because fields have no meaning for Gerber files
* and therefore the GUID generated has no meaning because it do not use any time and time stamp
* specific to the project, just a random pattern (random is here a pattern specific to a project).
*
* See en.wikipedia.org/wiki/Universally_unique_identifier
*/
wxString GbrMakeProjectGUIDfromString( wxString& aText );
// this class handle info which can be added in a gerber file as attribute
// of an aperture, by the %TA.AperFunction command

View File

@ -246,31 +246,15 @@ void GERBER_JOBFILE_WRITER::addJSONGeneralSpecs()
// <project id> is the name of the project, restricted to basic ASCII symbols only,
// and comma not accepted
// All illegal chars will be replaced by underscore
// <project GUID> is a 32 hexadecimal digits string which is an unique id of a project.
// This is a random 128-bit number expressed in 32 hexadecimal digits.
// See en.wikipedia.org/wiki/GUID for more information
// However Kicad does not handle such a project GUID, so it is built from the board name
// Rem: <project id> accepts only ASCII 7 code (only basic ASCII codes are allowed in gerber files).
//
// <project GUID> is a string which is an unique id of a project.
// However Kicad does not handle such a project GUID, so it is built from the board name
wxFileName fn = m_pcb->GetFileName();
wxString msg = fn.GetFullName();
wxString guid;
// Build a 32 digits GUID from the board name:
for( unsigned ii = 0; ii < msg.Len(); ii++ )
{
int cc1 = int( msg[ii] ) & 0x0F;
int cc2 = ( int( msg[ii] ) >> 4) & 0x0F;
guid << wxString::Format( wxT( "%X%X" ), cc2, cc1 );
if( guid.Len() >= 32 )
break;
}
// guid has 32 digits, so add missing digits
int cnt = 32 - guid.Len();
if( cnt > 0 )
guid.Append( '0', cnt );
// Build a <project GUID>, from the board name
wxString guid = GbrMakeProjectGUIDfromString( msg );
// build the <project id> string: this is the board short filename (without ext)
// and all non ASCII chars are replaced by '_'

View File

@ -42,6 +42,7 @@
#include <dialog_plot.h>
#include <macros.h>
#include <build_version.h>
#include <gbr_metadata.h>
const wxString GetGerberProtelExtension( LAYER_NUM aLayer )
@ -276,85 +277,6 @@ static wxString& makeStringCompatX1( wxString& aText, bool aUseX1CompatibilityMo
}
/** A helper function to build a project GUID using format RFC4122 Version 1 or 4
* from the project name, because a kicad project has no specific GUID
* RFC4122 is used mainly for its syntax, because fields have no meaning for Gerber files
* and therefore the GUID generated has no meaning because it do not use any time and time stamp
* specific to the project, just a random pattern (random is here a pattern specific to a project).
*
* See en.wikipedia.org/wiki/Universally_unique_identifier
*/
static wxString makeProjectGUIDfromString( wxString& aText )
{
// Gerber GUID format should be RFC4122 Version 1 or 4. The format is:
// xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
// with
// x = hexDigit lower/upper case
// and
// M = '1' or '4' (UUID version: 1 (basic) or 4 (random)) (we use 4: UUID random)
// and
// N = '8' or '9' or 'A|a' or 'B|b' : UUID variant 1: 2 MSB bits have meaning) (we use N = 9)
// N = 1000 or 1001 or 1010 or 1011 : 10xx means Variant 1 (Variant2: 110x and 111x are reserved)
wxString guid;
// Build a 32 digits GUID from the board name:
// guid has 32 digits, so add chars in name to be sure we can build a 32 digits guid
// (i.e. from a 16 char string name)
// In fact only 30 digits are used, and 2 UID id
wxString bname = aText;
int cnt = 16 - bname.Len();
if( cnt > 0 )
bname.Append( 'X', cnt );
int chr_idx = 0;
// Output the 8 first hex digits:
for( unsigned ii = 0; ii < 4; ii++ )
{
int cc = int( bname[chr_idx++] ) & 0xFF;
guid << wxString::Format( "%2.2x", cc );
}
// Output the 4 next hex digits:
guid << '-';
for( unsigned ii = 0; ii < 2; ii++ )
{
int cc = int( bname[chr_idx++] ) & 0xFF;
guid << wxString::Format( "%2.2x", cc );
}
// Output the 4 next hex digits (UUID version and 3 digits):
guid << "-4"; // first digit: UUID version 4 (M = 4)
{
int cc = int( bname[chr_idx++] ) << 4 & 0xFF0;
cc += int( bname[chr_idx] ) >> 4 & 0x0F;
guid << wxString::Format( "%3.3x", cc );
}
// Output the 4 next hex digits (UUID variant and 3 digits):
guid << "-9"; // first digit: UUID variant 1 (N = 9)
{
int cc = (int( bname[chr_idx++] ) & 0x0F) << 8;
cc += int( bname[chr_idx++] ) & 0xFF;
guid << wxString::Format( "%3.3x", cc );
}
// Output the 12 last hex digits:
guid << '-';
for( unsigned ii = 0; ii < 6; ii++ )
{
int cc = int( bname[chr_idx++] ) & 0xFF;
guid << wxString::Format( "%2.2x", cc );
}
return guid;
}
void AddGerberX2Header( PLOTTER * aPlotter,
const BOARD *aBoard, bool aUseX1CompatibilityMode )
{
@ -393,7 +315,7 @@ void AddGerberX2Header( PLOTTER * aPlotter,
msg = fn.GetFullName();
// Build a <project GUID>, from the board name
wxString guid = makeProjectGUIDfromString( msg );
wxString guid = GbrMakeProjectGUIDfromString( msg );
// build the <project id> string: this is the board short filename (without ext)
// and all non ASCII chars and comma are replaced by '_'