Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
K
kicad-source-mirror
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
Elphel
kicad-source-mirror
Commits
06390721
Commit
06390721
authored
Dec 08, 2012
by
Dick Hollenbeck
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
more fp_lib_table work, enhance parser
parent
6ad94a49
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
252 additions
and
144 deletions
+252
-144
dsnlexer.cpp
common/dsnlexer.cpp
+4
-6
fp_lib_table.cpp
common/fp_lib_table.cpp
+100
-42
fp_lib_table.keywords
common/fp_lib_table.keywords
+3
-5
richio.cpp
common/richio.cpp
+41
-10
fp_lib_table.h
include/fp_lib_table.h
+61
-59
richio.h
include/richio.h
+2
-18
pcb_plot_params.h
pcbnew/pcb_plot_params.h
+3
-4
pcbnew_config.cpp
pcbnew/pcbnew_config.cpp
+38
-0
No files found.
common/dsnlexer.cpp
View file @
06390721
...
...
@@ -304,9 +304,8 @@ void DSNLEXER::Unexpected( int aTok ) throw( IO_ERROR )
void
DSNLEXER
::
Duplicate
(
int
aTok
)
throw
(
IO_ERROR
)
{
wxString
errText
;
errText
.
Printf
(
_
(
"%s is a duplicate"
),
GetTokenString
(
aTok
).
GetData
()
);
wxString
errText
=
wxString
::
Format
(
_
(
"%s is a duplicate"
),
GetTokenString
(
aTok
).
GetData
()
);
THROW_PARSE_ERROR
(
errText
,
CurSource
(),
CurLine
(),
CurLineNumber
(),
CurOffset
()
);
}
...
...
@@ -358,9 +357,8 @@ int DSNLEXER::NeedNUMBER( const char* aExpectation ) throw( IO_ERROR )
int
tok
=
NextTok
();
if
(
tok
!=
DSN_NUMBER
)
{
wxString
errText
;
errText
.
Printf
(
_
(
"need a NUMBER for '%s'"
),
wxString
::
FromUTF8
(
aExpectation
).
GetData
()
);
wxString
errText
=
wxString
::
Format
(
_
(
"need a NUMBER for '%s'"
),
wxString
::
FromUTF8
(
aExpectation
).
GetData
()
);
THROW_PARSE_ERROR
(
errText
,
CurSource
(),
CurLine
(),
CurLineNumber
(),
CurOffset
()
);
}
return
tok
;
...
...
common/fp_lib_table.cpp
View file @
06390721
...
...
@@ -24,6 +24,8 @@
*/
#include <wx/config.h> // wxExpandEnvVars()
#include <set>
#include <io_mgr.h>
...
...
@@ -45,11 +47,29 @@ FP_LIB_TABLE::FP_LIB_TABLE( FP_LIB_TABLE* aFallBackTable ) :
void
FP_LIB_TABLE
::
Parse
(
FP_LIB_TABLE_LEXER
*
in
)
throw
(
IO_ERROR
,
PARSE_ERROR
)
{
/*
(fp_lib_table
(lib (name NICKNAME)(descr DESCRIPTION)(type TYPE)(full_uri FULL_URI)(options OPTIONS))
:
)
Elements after (name) are order independent.
*/
T
tok
;
// This table may be nested within a larger s-expression, or not.
// Allow for parser of that optional outter s-epression to have looked ahead.
if
(
in
->
CurTok
()
!=
T_fp_lib_table
)
{
in
->
NeedLEFT
();
if
(
(
tok
=
in
->
NextTok
()
)
!=
T_fp_lib_table
)
in
->
Expecting
(
T_fp_lib_table
);
}
while
(
(
tok
=
in
->
NextTok
()
)
!=
T_RIGHT
)
{
// (lib (name "LOGICAL")(type "TYPE")(full_uri "FULL_URI")(options "OPTIONS"))
ROW
row
;
// reconstructed for each row in input stream.
if
(
tok
==
T_EOF
)
in
->
Expecting
(
T_RIGHT
);
...
...
@@ -57,10 +77,14 @@ void FP_LIB_TABLE::Parse( FP_LIB_TABLE_LEXER* in ) throw( IO_ERROR, PARSE_ERROR
if
(
tok
!=
T_LEFT
)
in
->
Expecting
(
T_LEFT
);
if
(
(
tok
=
in
->
NextTok
()
)
!=
T_fp_lib
)
in
->
Expecting
(
T_fp_lib
);
// in case there is a "row integrity" error, tell where later.
int
lineNum
=
in
->
CurLineNumber
();
int
offset
=
in
->
CurOffset
();
if
(
(
tok
=
in
->
NextTok
()
)
!=
T_lib
)
in
->
Expecting
(
T_lib
);
// (name
"LOGICAL_NAME"
)
// (name
LOGICAL_NAME
)
in
->
NeedLEFT
();
if
(
(
tok
=
in
->
NextTok
()
)
!=
T_name
)
...
...
@@ -68,48 +92,74 @@ void FP_LIB_TABLE::Parse( FP_LIB_TABLE_LEXER* in ) throw( IO_ERROR, PARSE_ERROR
in
->
NeedSYMBOLorNUMBER
();
ROW
row
;
row
.
SetNickName
(
in
->
FromUTF8
()
);
in
->
NeedRIGHT
();
// (uri "FULL_URI")
in
->
NeedLEFT
();
if
(
(
tok
=
in
->
NextTok
()
)
!=
T_full_uri
)
in
->
Expecting
(
T_full_uri
);
in
->
NeedSYMBOLorNUMBER
();
// After (name), remaining (lib) elements are order independent, and in
// the future, perhaps optional. Flexibility for future changes.
row
.
SetFullURI
(
in
->
FromUTF8
()
);
bool
sawType
=
false
;
bool
sawOpts
=
false
;
bool
sawDesc
=
false
;
bool
sawUri
=
false
;
in
->
NeedRIGHT
();
while
(
(
tok
=
in
->
NextTok
()
)
!=
T_RIGHT
)
{
if
(
tok
==
T_EOF
)
in
->
Unexpected
(
T_EOF
);
// (type "TYPE"
)
in
->
NeedLEFT
(
);
if
(
tok
!=
T_LEFT
)
in
->
Expecting
(
T_LEFT
);
if
(
(
tok
=
in
->
NextTok
()
)
!=
T_type
)
in
->
Expecting
(
T_type
);
tok
=
in
->
NeedSYMBOLorNUMBER
();
switch
(
tok
)
{
case
T_uri
:
if
(
sawUri
)
in
->
Duplicate
(
tok
);
sawUri
=
true
;
in
->
NeedSYMBOLorNUMBER
();
row
.
SetFullURI
(
in
->
FromUTF8
()
);
break
;
case
T_type
:
if
(
sawType
)
in
->
Duplicate
(
tok
);
sawType
=
true
;
in
->
NeedSYMBOLorNUMBER
();
row
.
SetType
(
in
->
FromUTF8
()
);
break
;
in
->
NeedRIGHT
();
// (options "OPTIONS")
in
->
NeedLEFT
()
;
if
(
(
tok
=
in
->
NextTok
()
)
!=
T_options
)
in
->
Expecting
(
T_options
)
;
case
T_options
:
if
(
sawOpts
)
in
->
Duplicate
(
tok
);
sawOpts
=
true
;
in
->
NeedSYMBOLorNUMBER
();
row
.
SetOptions
(
in
->
FromUTF8
()
);
break
;
case
T_descr
:
if
(
sawDesc
)
in
->
Duplicate
(
tok
);
sawDesc
=
true
;
in
->
NeedSYMBOLorNUMBER
();
row
.
SetDescr
(
in
->
FromUTF8
()
);
break
;
row
.
SetOptions
(
in
->
FromUTF8
()
);
default
:
in
->
Unexpected
(
tok
);
}
in
->
NeedRIGHT
();
in
->
NeedRIGHT
();
// terminate the (lib..)
}
if
(
!
sawType
)
in
->
Expecting
(
T_type
);
if
(
!
sawUri
)
in
->
Expecting
(
T_uri
);
// all nickNames within this table fragment must be unique, so we do not
// use doReplace in InsertRow(). (However a fallBack table can have a
...
...
@@ -119,9 +169,8 @@ void FP_LIB_TABLE::Parse( FP_LIB_TABLE_LEXER* in ) throw( IO_ERROR, PARSE_ERROR
{
wxString
msg
=
wxString
::
Format
(
_
(
"'%s' is a duplicate footprint library nickName"
),
GetChars
(
row
.
nickName
)
);
THROW_IO_ERROR
(
msg
);
GetChars
(
row
.
nickName
)
);
THROW_PARSE_ERROR
(
msg
,
in
->
CurSource
(),
in
->
CurLine
(),
lineNum
,
offset
);
}
}
}
...
...
@@ -142,8 +191,9 @@ void FP_LIB_TABLE::Format( OUTPUTFORMATTER* out, int nestLevel ) const
void
FP_LIB_TABLE
::
ROW
::
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
const
throw
(
IO_ERROR
)
{
out
->
Print
(
nestLevel
,
"(lib (name %s)(
full_
uri %s)(type %s)(options %s))
\n
"
,
out
->
Print
(
nestLevel
,
"(lib (name %s)(
descr %s)(
uri %s)(type %s)(options %s))
\n
"
,
out
->
Quotew
(
GetNickName
()
).
c_str
(),
out
->
Quotew
(
GetDescr
()
).
c_str
(),
out
->
Quotew
(
GetFullURI
()
).
c_str
(),
out
->
Quotew
(
GetType
()
).
c_str
(),
out
->
Quotew
(
GetOptions
()
).
c_str
()
...
...
@@ -252,6 +302,14 @@ PLUGIN* FP_LIB_TABLE::PluginFind( const wxString& aLibraryNickName )
}
const
wxString
FP_LIB_TABLE
::
ExpandSubtitutions
(
const
wxString
aString
)
{
// We reserve the right to do this another way, but providing our own member
// function.
return
wxExpandEnvVars
(
aString
);
}
#if 0 // don't know that this is needed yet
MODULE* FP_LIB_TABLE::LookupFootprint( const FP_LIB_ID& aFootprintId )
throw( IO_ERROR )
...
...
common/fp_lib_table.keywords
View file @
06390721
fp_lib_table
lib
name
type
kicad
legacy
eagle
full_uri
uri
options
fp_lib
descr
common/richio.cpp
View file @
06390721
...
...
@@ -39,15 +39,44 @@
// "richio" after its author, Richard Hollenbeck, aka Dick Hollenbeck.
void
IO_ERROR
::
init
(
const
char
*
aThrowersFile
,
const
char
*
aThrowersLoc
,
const
wxString
&
aMsg
)
{
errorText
.
Printf
(
IO_FORMAT
,
aMsg
.
GetData
(),
wxString
::
FromUTF8
(
aThrowersFile
).
GetData
(),
wxString
::
FromUTF8
(
aThrowersLoc
).
GetData
()
);
}
void
PARSE_ERROR
::
init
(
const
char
*
aThrowersFile
,
const
char
*
aThrowersLoc
,
const
wxString
&
aMsg
,
const
wxString
&
aSource
,
const
char
*
aInputLine
,
int
aLineNumber
,
int
aByteIndex
)
{
// save inpuLine, lineNumber, and offset for UI (.e.g. Sweet text editor)
inputLine
=
aInputLine
;
lineNumber
=
aLineNumber
;
byteIndex
=
aByteIndex
;
errorText
.
Printf
(
PARSE_FORMAT
,
aMsg
.
GetData
(),
aSource
.
GetData
(),
aLineNumber
,
aByteIndex
,
wxString
::
FromUTF8
(
aThrowersFile
).
GetData
(),
wxString
::
FromUTF8
(
aThrowersLoc
).
GetData
()
);
}
//-----<LINE_READER>------------------------------------------------------
LINE_READER
::
LINE_READER
(
unsigned
aMaxLineLength
)
{
lineNum
=
0
;
if
(
aMaxLineLength
==
0
)
// caller is goofed up.
aMaxLineLength
=
LINE_READER_LINE_DEFAULT_MAX
;
if
(
aMaxLineLength
==
0
)
{
line
=
0
;
}
else
{
maxLineLength
=
aMaxLineLength
;
// start at the INITIAL size, expand as needed up to the MAX size in maxLineLength
...
...
@@ -60,6 +89,8 @@ LINE_READER::LINE_READER( unsigned aMaxLineLength )
line
=
new
char
[
capacity
];
line
[
0
]
=
'\0'
;
}
length
=
0
;
}
...
...
include/fp_lib_table.h
View file @
06390721
...
...
@@ -41,7 +41,7 @@ class FP_LIB_TABLE_LEXER;
/**
* Class FP_LIB_TABLE
* holds FP_LIB_TABLE::ROW records
, and can be searched based on logical library n
ame.
* holds FP_LIB_TABLE::ROW records
(rows), and can be searched based on library nickN
ame.
* <p>
* This class owns the <b>footprint library table</b>, which is like fstab in concept and maps
* logical library name to the library URI, type, and options. It is heavily based on the SWEET
...
...
@@ -104,10 +104,12 @@ public:
{
}
ROW
(
const
wxString
&
aNick
,
const
wxString
&
aURI
,
const
wxString
&
aType
,
const
wxString
&
aOptions
)
:
ROW
(
const
wxString
&
aNick
,
const
wxString
&
aURI
,
const
wxString
&
aType
,
const
wxString
&
aOptions
,
const
wxString
&
aDescr
=
wxEmptyString
)
:
nickName
(
aNick
),
uri
(
aURI
),
options
(
aOptions
)
options
(
aOptions
),
description
(
aDescr
)
{
SetType
(
aType
);
}
...
...
@@ -119,90 +121,80 @@ public:
bool
operator
!=
(
const
ROW
&
r
)
const
{
return
!
(
*
this
==
r
);
}
//-----<accessors>------------------------------------------------------
/**
* Function GetNickName
* returns the short name of this library table row.
*/
const
wxString
&
GetNickName
()
const
{
return
nickName
;
}
const
wxString
&
GetNickName
()
const
{
return
nickName
;
}
/**
* Function SetNickName
* changes the logical name of this library, useful for an editor.
*/
void
SetNickName
(
const
wxString
&
aNickName
)
{
nickName
=
aNickName
;
}
/**
* Function GetType
* returns the type of LIB represented by this r
ecord
.
* returns the type of LIB represented by this r
ow
.
*/
const
wxString
GetType
()
const
{
return
IO_MGR
::
ShowType
(
type
);
}
const
wxString
GetType
()
const
{
return
IO_MGR
::
ShowType
(
type
);
}
/**
* Function SetType
* changes the type represented by this row.
*/
void
SetType
(
const
wxString
&
aType
)
{
type
=
IO_MGR
::
EnumFromStr
(
aType
);
}
/**
* Function GetFullURI
* returns the full location specifying URI for the LIB.
*/
const
wxString
&
GetFullURI
()
const
{
return
uri
;
}
const
wxString
&
GetFullURI
()
const
{
return
uri
;
}
/**
* Function SetFullURI
* changes the full URI for the library.
*/
void
SetFullURI
(
const
wxString
&
aFullURI
)
{
uri
=
aFullURI
;
}
/**
* Function GetOptions
* returns the options string, which may hold a password or anything else needed to
* instantiate the underlying LIB_SOURCE.
*/
const
wxString
&
GetOptions
()
const
{
return
options
;
}
const
wxString
&
GetOptions
()
const
{
return
options
;
}
/**
* Function Format
* serializes this object as utf8 text to an OUTPUTFORMATTER, and tries to
* make it look good using multiple lines and indentation.
* @param out is an #OUTPUTFORMATTER
* @param nestLevel is the indentation level to base all lines of the output.
* Actual indentation will be 2 spaces for each nestLevel.
* Function SetOptions
*/
void
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
const
throw
(
IO_ERROR
);
void
SetOptions
(
const
wxString
&
aOptions
)
{
options
=
aOptions
;
}
/**
* Function
SetNickName
*
changes the logical name of this library, useful for an editor
.
* Function
GetDescr
*
returns the description of the library referenced by this row
.
*/
void
SetNickName
(
const
wxString
&
aNickName
)
{
nickName
=
aNickName
;
}
const
wxString
&
GetDescr
()
const
{
return
description
;
}
/**
* Function Set
Type
* changes the
type represented by this record
.
* Function Set
Descr
* changes the
description of the library referenced by this row
.
*/
void
SetType
(
const
wxString
&
aType
)
{
type
=
IO_MGR
::
EnumFromStr
(
aType
);
}
void
SetDescr
(
const
wxString
&
aDescr
)
{
description
=
aDescr
;
}
/**
* Function SetFullURI
* changes the full URI for the library, useful from a library table editor.
*/
void
SetFullURI
(
const
wxString
&
aFullURI
)
{
uri
=
aFullURI
;
}
//-----</accessors>-----------------------------------------------------
/**
* Function SetOptions
* changes the options string for this record, and is useful from
* the library table editor.
* Function Format
* serializes this object as utf8 text to an OUTPUTFORMATTER, and tries to
* make it look good using multiple lines and indentation.
* @param out is an #OUTPUTFORMATTER
* @param nestLevel is the indentation level to base all lines of the output.
* Actual indentation will be 2 spaces for each nestLevel.
*/
void
SetOptions
(
const
wxString
&
aOptions
)
{
options
=
aOptions
;
}
void
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
const
throw
(
IO_ERROR
);
private
:
...
...
@@ -210,6 +202,7 @@ public:
wxString
uri
;
LIB_T
type
;
wxString
options
;
wxString
description
;
};
...
...
@@ -219,7 +212,7 @@ public:
* @a aFallBackTable. Loading of this table fragment is done by using Parse().
*
* @param aFallBackTable is another FP_LIB_TABLE which is searched only when
* a r
ecord
is not found in this table. No ownership is
* a r
ow
is not found in this table. No ownership is
* taken of aFallBackTable.
*/
FP_LIB_TABLE
(
FP_LIB_TABLE
*
aFallBackTable
=
NULL
);
...
...
@@ -249,9 +242,9 @@ public:
*
* <pre>
* (fp_lib_table
* (lib (name LOGICAL)(
type TYPE)(uri FULL_URI
)(options OPTIONS))
* (lib (name LOGICAL)(
type TYPE)(uri FULL_URI
)(options OPTIONS))
* (lib (name LOGICAL)(
type TYPE)(uri FULL_URI
)(options OPTIONS))
* (lib (name LOGICAL)(
descr DESCRIPTION)(uri FULL_URI)(type TYPE
)(options OPTIONS))
* (lib (name LOGICAL)(
descr DESCRIPTION)(uri FULL_URI)(type TYPE
)(options OPTIONS))
* (lib (name LOGICAL)(
descr DESCRIPTION)(uri FULL_URI)(type TYPE
)(options OPTIONS))
* )
* </pre>
*
...
...
@@ -363,6 +356,15 @@ public:
const
ROW
*
FindRow
(
const
wxString
&
aNickName
)
throw
(
IO_ERROR
);
/**
* Function ExpandEnvSubsitutions
* replaces any environment variable references with their values and is
* here to fully embellish the ROW::uri in a platform independent way.
* This enables (fp_lib_table)s to have platform dependent environment
* variables in them, allowing for a uniform table across platforms.
*/
static
const
wxString
ExpandSubtitutions
(
const
wxString
aString
);
protected
:
/**
...
...
include/richio.h
View file @
06390721
...
...
@@ -115,12 +115,7 @@ struct IO_ERROR // : std::exception
init
(
aThrowersFile
,
aThrowersLoc
,
wxString
(
aMsg
)
);
}
void
init
(
const
char
*
aThrowersFile
,
const
char
*
aThrowersLoc
,
const
wxString
&
aMsg
)
{
errorText
.
Printf
(
IO_FORMAT
,
aMsg
.
GetData
(),
wxString
::
FromUTF8
(
aThrowersFile
).
GetData
(),
wxString
::
FromUTF8
(
aThrowersLoc
).
GetData
()
);
}
void
init
(
const
char
*
aThrowersFile
,
const
char
*
aThrowersLoc
,
const
wxString
&
aMsg
);
IO_ERROR
()
{}
...
...
@@ -165,18 +160,7 @@ struct PARSE_ERROR : public IO_ERROR
void
init
(
const
char
*
aThrowersFile
,
const
char
*
aThrowersLoc
,
const
wxString
&
aMsg
,
const
wxString
&
aSource
,
const
char
*
aInputLine
,
int
aLineNumber
,
int
aByteIndex
)
{
// save inpuLine, lineNumber, and offset for UI (.e.g. Sweet text editor)
inputLine
=
aInputLine
;
lineNumber
=
aLineNumber
;
byteIndex
=
aByteIndex
;
errorText
.
Printf
(
PARSE_FORMAT
,
aMsg
.
GetData
(),
aSource
.
GetData
(),
aLineNumber
,
aByteIndex
,
wxString
::
FromUTF8
(
aThrowersFile
).
GetData
(),
wxString
::
FromUTF8
(
aThrowersLoc
).
GetData
()
);
}
int
aLineNumber
,
int
aByteIndex
);
~
PARSE_ERROR
()
throw
(
/*none*/
){}
};
...
...
pcbnew/pcb_plot_params.h
View file @
06390721
...
...
@@ -292,5 +292,4 @@ public:
*/
extern
int
g_DrawDefaultLineThickness
;
#endif // PCB_PLOT_PARAMS_H_
pcbnew/pcbnew_config.cpp
View file @
06390721
...
...
@@ -45,6 +45,10 @@
#include <class_board.h>
#include <fp_lib_table.h>
#if defined(DEBUG)
#include <fp_lib_table_lexer.h>
#endif
#include <pcbplot.h>
#include <pcbnew.h>
#include <pcbnew_id.h>
...
...
@@ -88,6 +92,39 @@ void PCB_EDIT_FRAME::Process_Config( wxCommandEvent& event )
FP_LIB_TABLE
gbl
;
FP_LIB_TABLE
prj
;
#if defined(DEBUG)
FP_LIB_TABLE_LEXER
glex
(
"(fp_lib_table
\n
"
" (lib (name passives)(descr
\"
Demo Lib
\"
)(type KiCad)(uri ${KISFP}/passives.pretty))
\n
"
" (lib (name micros)(descr
\"
Small stuff
\"
)(type Legacy)(uri ${KISFP}/passives.mod)(options
\"
op1=2
\"
))
\n
"
" (lib (name chips)(descr
\"
Potatoe chips
\"
)(type Eagle)(uri /opt/eagle-6.2.0/lbr/con-amp-micromatch.lbr))
\n
"
")"
,
wxT
(
"gbl"
)
);
FP_LIB_TABLE_LEXER
plex
(
"(fp_lib_table
\n
"
" (lib (name passives)(descr
\"
Demo Lib
\"
)(type KiCad)(uri ${KIUFP}/passives.pretty))
\n
"
" (lib (name micros)(descr
\"
Small stuff
\"
)(type Legacy)(uri ${KIUFP}/micros.mod)(options
\"
op1=2
\"
))
\n
"
" (lib (name chips)(descr
\"
Potatoe chips
\"
)(type Eagle)(uri /opt/eagle-6.2.0/lbr/con-amp-micromatch.lbr))
\n
"
")"
,
wxT
(
"prj"
)
);
try
{
gbl
.
Parse
(
&
glex
);
prj
.
Parse
(
&
plex
);
}
/* PARSE_ERROR is an IO_ERROR, handle them the same for now.
catch( PARSE_ERROR pe )
{
DisplayError( this, pe.errorText );
break;
}
*/
catch
(
IO_ERROR
ioe
)
{
DisplayError
(
this
,
ioe
.
errorText
);
break
;
}
#else
gbl
.
InsertRow
(
FP_LIB_TABLE
::
ROW
(
wxT
(
"passives"
),
wxT
(
"%G/passives"
),
wxT
(
"KiCad"
),
wxT
(
"speed=fast,purpose=testing"
)
)
);
...
...
@@ -96,6 +133,7 @@ void PCB_EDIT_FRAME::Process_Config( wxCommandEvent& event )
prj
.
InsertRow
(
FP_LIB_TABLE
::
ROW
(
wxT
(
"micros"
),
wxT
(
"%P/potato_chips"
),
wxT
(
"Eagle"
),
wxT
(
"speed=fast,purpose=testing"
)
)
);
#endif
int
r
=
InvokePcbLibTableEditor
(
this
,
&
gbl
,
&
prj
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment