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
0d3fd5d1
Commit
0d3fd5d1
authored
Jan 01, 2008
by
dickelbeck
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
more specctra work
parent
1afb0498
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
516 additions
and
66 deletions
+516
-66
dsn.cpp
pcbnew/dsn.cpp
+100
-12
dsn.h
pcbnew/dsn.h
+46
-26
specctra.cpp
pcbnew/specctra.cpp
+370
-28
No files found.
pcbnew/dsn.cpp
View file @
0d3fd5d1
...
...
@@ -156,6 +156,7 @@ const static KEYWORD tokens[] = {
TOKDEF
(
host_cad
),
TOKDEF
(
host_version
),
TOKDEF
(
image
),
TOKDEF
(
image_conductor
),
TOKDEF
(
image_image
),
TOKDEF
(
image_image_spacing
),
TOKDEF
(
image_outline_clearance
),
...
...
@@ -464,6 +465,25 @@ int LINE_READER::ReadLine() throw (IOError)
//-----<LEXER>-------------------------------------------------------------
LEXER
::
LEXER
(
FILE
*
aFile
,
const
wxString
&
aFilename
)
:
reader
(
aFile
,
4096
)
{
curTok
=
T_END
;
stringDelimiter
=
'"'
;
filename
=
aFilename
;
space_in_quoted_tokens
=
false
;
// "start" should never change until we change the reader. The DSN
// format spec supports an include file mechanism but we can add that later
// using a std::stack to hold a stack of LINE_READERs to track nesting.
start
=
(
char
*
)
reader
;
limit
=
start
;
next
=
start
;
}
int
LEXER
::
findToken
(
const
std
::
string
&
tok
)
{
// convert to lower case once, this should be faster than using strcasecmp()
...
...
@@ -486,15 +506,69 @@ int LEXER::findToken( const std::string& tok )
}
wxString
LEXER
::
GetTokenText
(
DSN_T
aTok
)
{
wxString
ret
;
if
(
aTok
<
0
)
{
switch
(
aTok
)
{
case
T_QUOTE_DEF
:
ret
<<
_
(
"'quoted text delimiter'"
);
break
;
case
T_DASH
:
ret
<<
wxT
(
"'-'"
);
break
;
case
T_SYMBOL
:
ret
<<
_
(
"'symbol'"
);
break
;
case
T_NUMBER
:
ret
<<
_
(
"'number'"
);
break
;
case
T_RIGHT
:
ret
<<
wxT
(
"')'"
);
break
;
case
T_LEFT
:
ret
<<
wxT
(
"'('"
);
break
;
case
T_STRING
:
ret
<<
_
(
"
\"
quoted string
\"
"
);
break
;
case
T_EOF
:
ret
<<
_
(
"'end of file'"
);
break
;
default
:
;
}
}
else
{
ret
<<
wxT
(
"'"
)
<<
CONV_FROM_UTF8
(
tokens
[
aTok
].
name
)
<<
wxT
(
"'"
);
}
return
ret
;
}
void
LEXER
::
ThrowIOError
(
wxString
aText
,
int
charOffset
)
throw
(
IOError
)
{
aText
<<
wxT
(
" "
)
<<
_
(
"in file"
)
<<
wxT
(
"
\"
"
)
<<
filename
<<
wxT
(
"
\"
"
)
<<
_
(
"on line"
)
<<
wxT
(
" "
)
<<
reader
.
LineNumber
()
<<
wxT
(
" "
)
<<
_
(
"at offset"
)
<<
wxT
(
" "
)
<<
charOffset
;
throw
IOError
(
aText
);
}
DSN_T
LEXER
::
NextTok
()
throw
(
IOError
)
{
char
*
head
;
char
*
cur
;
char
*
cur
=
next
;
char
*
head
=
cur
;
lastTok
=
curTok
;
cur
=
next
;
if
(
curTok
!=
T_EOF
)
{
if
(
cur
>=
limit
)
...
...
@@ -520,15 +594,27 @@ L_read:
// switching the string_quote character
if
(
lastTok
==
T_string_quote
)
{
static
const
wxString
errtxt
(
_
(
"String delimiter must be a single character of ',
\"
, or $"
));
char
cc
=
*
cur
;
switch
(
cc
)
{
case
'\''
:
case
'$'
:
case
'"'
:
break
;
default
:
ThrowIOError
(
errtxt
,
CurOffset
()
);
}
curText
.
clear
();
curText
+=
*
cur
;
curText
+=
cc
;
head
=
cur
+
1
;
if
(
head
<
limit
&&
*
head
!=
')'
&&
*
head
!=
'('
&&
!
isspace
(
*
head
)
)
{
wxString
errtxt
(
_
(
"String delimiter char must be a single char"
)
);
ThrowIOError
(
errtxt
,
cur
-
start
+
1
);
ThrowIOError
(
errtxt
,
CurOffset
()
);
}
curTok
=
T_QUOTE_DEF
;
...
...
@@ -578,17 +664,17 @@ L_read:
// a quoted string
else
if
(
*
cur
==
stringDelimiter
)
{
++
cur
;
// skip over the leading
"
++
cur
;
// skip over the leading
delimiter: ",', or $
head
=
cur
;
while
(
head
<
limit
&&
*
head
!=
stringDelimiter
)
while
(
head
<
limit
&&
!
isStringTerminator
(
*
head
)
)
++
head
;
if
(
head
>=
limit
)
{
wxString
errtxt
(
_
(
"Un-terminated delimited string"
)
);
ThrowIOError
(
errtxt
,
cur
-
start
+
1
);
ThrowIOError
(
errtxt
,
CurOffset
()
);
}
curText
.
clear
();
...
...
@@ -630,6 +716,8 @@ L_read:
exit
:
// single point of exit
curOffset
=
cur
-
start
;
next
=
head
;
return
curTok
;
...
...
@@ -640,7 +728,7 @@ exit: // single point of exit
#if defined(STANDALONE)
#if
0 &&
defined(STANDALONE)
// stand alone testing
...
...
pcbnew/dsn.h
View file @
0d3fd5d1
...
...
@@ -42,11 +42,10 @@ namespace DSN {
enum
DSN_T
{
// the first few are special (the uppercase ones)
T_QUOTE_DEF
=
-
9
,
T_DASH
=
-
8
,
T_SYMBOL
=
-
7
,
T_NUMBER
=
-
6
,
T_NONE
=
-
5
,
// not a token
T_QUOTE_DEF
=
-
8
,
T_DASH
=
-
7
,
T_SYMBOL
=
-
6
,
T_NUMBER
=
-
5
,
T_RIGHT
=
-
4
,
// right bracket, ')'
T_LEFT
=
-
3
,
// left bracket, '('
T_STRING
=
-
2
,
// a quoted string, stripped of the quotes
...
...
@@ -157,6 +156,7 @@ enum DSN_T {
T_host_cad
,
T_host_version
,
T_image
,
T_image_conductor
,
T_image_image
,
T_image_image_spacing
,
T_image_outline_clearance
,
...
...
@@ -513,8 +513,11 @@ class LEXER
LINE_READER
reader
;
int
stringDelimiter
;
bool
space_in_quoted_tokens
;
///< blank spaces within quoted strings
wxString
filename
;
int
lastTok
;
///< curTok from previous NextTok() call.
int
curOffset
;
///< offset within current line of the current token
DSN_T
curTok
;
///< the current token obtained on last NextTok()
std
::
string
curText
;
///< the text of the current token
...
...
@@ -543,24 +546,22 @@ class LEXER
*/
int
findToken
(
const
std
::
string
&
tok
);
public
:
LEXER
(
FILE
*
aFile
,
const
wxString
&
aFilename
)
:
reader
(
aFile
,
4096
)
bool
isStringTerminator
(
char
cc
)
{
curTok
=
T_NONE
;
stringDelimiter
=
'"'
;
filename
=
aFilename
;
if
(
!
space_in_quoted_tokens
&&
cc
==
' '
)
return
true
;
// "start" should never change until we change the reader. The DSN
// format spec supports an include file mechanism but we can add that later
// using a std::stack to hold a stack of LINE_READERs to track nesting.
start
=
(
char
*
)
reader
;
if
(
cc
==
stringDelimiter
)
return
true
;
limit
=
start
;
next
=
start
;
return
false
;
}
public
:
LEXER
(
FILE
*
aFile
,
const
wxString
&
aFilename
);
/**
* Function SetStringDelimiter
* changes the string delimiter from the default " to some other character
...
...
@@ -575,6 +576,19 @@ public:
return
old
;
}
/**
* Function SetSpaceInQuotedTokens
* changes the setting controlling whether a space in a quoted string is
* a terminator
*/
bool
SetSpaceInQuotedTokens
(
bool
val
)
{
bool
old
=
space_in_quoted_tokens
;
space_in_quoted_tokens
=
val
;
return
old
;
}
/**
* Function NextTok
* returns the next token found in the input file or T_EOF when reaching
...
...
@@ -590,14 +604,10 @@ public:
* encapsulates the formatting of an error message which contains the exact
* location within the input file of a lexical error.
*/
void
ThrowIOError
(
wxString
aText
,
int
charOffset
)
throw
(
IOError
)
{
aText
<<
wxT
(
" "
)
<<
_
(
"in file"
)
<<
wxT
(
"
\"
"
)
<<
filename
<<
wxT
(
"
\"
"
)
<<
_
(
"on line"
)
<<
wxT
(
" "
)
<<
reader
.
LineNumber
()
<<
wxT
(
" "
)
<<
_
(
"at offset"
)
<<
wxT
(
" "
)
<<
charOffset
;
void
ThrowIOError
(
wxString
aText
,
int
charOffset
)
throw
(
IOError
);
throw
IOError
(
aText
);
}
wxString
GetTokenText
(
DSN_T
aTok
);
/**
...
...
@@ -619,6 +629,16 @@ public:
return
curTok
;
}
/**
* Function CurOffset
* returns the char offset within the current line, using a 1 based index.
* @return int - a one based index into the current line.
*/
int
CurOffset
()
{
return
curOffset
+
1
;
}
};
...
...
pcbnew/specctra.cpp
View file @
0d3fd5d1
...
...
@@ -29,7 +29,7 @@
#include <boost/ptr_container/ptr_vector.hpp>
#include <wx/ffile.h>
#include "fctsys.h"
#include "pcbstruct.h"
...
...
@@ -43,7 +43,6 @@ namespace DSN {
* is a base class for any DSN element. It is not a parent node so it
* cannot contain other elements but it can be extended to hold fields
* for any DSN element which contains no other elements, only fields.
*/
class ELEM
{
protected:
...
...
@@ -58,26 +57,24 @@ public:
virtual ~ELEM()
{
printf
(
"~ELEM(%p %d)
\n
"
,
this
,
Type
()
);
//
printf("~ELEM(%p %d)\n", this, Type() );
}
DSN_T
Type
()
{
return
type
;
}
virtual
void
Test
()
{
printf
(
"virtual Test()
\n
"
);
}
};
*/
/**
* Class
PARENT
* is a
base class
holder for any DSN element. It can contain other
* Class
ELEM
* is a holder for any DSN element. It can contain other
* elements, including elements derived from this class.
*/
class
PARENT
:
public
ELEM
class
ELEM
{
protected
:
DSN_T
type
;
// see http://www.boost.org/libs/ptr_container/doc/ptr_sequence_adapter.html
typedef
boost
::
ptr_vector
<
ELEM
>
ELEM_ARRAY
;
...
...
@@ -86,18 +83,53 @@ public:
public
:
PARENT
(
DSN_T
aType
)
:
ELEM
(
aType
)
ELEM
(
DSN_T
aType
)
:
type
(
aType
)
{
}
virtual
~
PARENT
()
virtual
~
ELEM
()
{
printf
(
"~PARENT
(%p %d)
\n
"
,
this
,
Type
()
);
// printf("~ELEM
(%p %d)\n", this, Type() );
}
DSN_T
Type
()
{
return
type
;
}
//-----< list operations >--------------------------------------------
/**
* Function FindElem
* finds a particular instance number of a given type of ELEM.
* @param aType The type of ELEM to find
* @param instanceNum The instance number of to find: 0 for first, 1 for second, etc.
* @return int - The index into the kids array or -1 if not found.
*/
int
FindElem
(
DSN_T
aType
,
int
instanceNum
)
{
int
repeats
=
0
;
for
(
unsigned
i
=
0
;
i
<
kids
.
size
();
++
i
)
{
if
(
kids
[
i
].
Type
()
==
aType
)
{
if
(
repeats
==
instanceNum
)
return
i
;
++
repeats
;
}
}
return
-
1
;
}
/**
* Function Length
* returns the number ELEMs in this ELEM.
* @return int - the count of children
*/
int
Length
()
const
{
return
kids
.
size
();
}
void
Append
(
ELEM
*
aElem
)
{
kids
.
push_back
(
aElem
);
...
...
@@ -115,6 +147,7 @@ public:
return
ret
.
release
();
}
/*
ELEM& operator[]( int aIndex )
{
return kids[aIndex];
...
...
@@ -124,14 +157,17 @@ public:
{
return kids[aIndex];
}
*/
void
Insert
(
int
aIndex
,
ELEM
*
aElem
)
{
kids
.
insert
(
kids
.
begin
()
+
aIndex
,
aElem
);
}
ELEM
*
At
(
int
aIndex
)
ELEM
*
operator
[]
(
int
aIndex
)
{
// we have varying sized object and are using polymorphism, so we
// must return a pointer not a reference.
return
&
kids
[
aIndex
];
}
...
...
@@ -139,20 +175,20 @@ public:
{
kids
.
erase
(
kids
.
begin
()
+
aIndex
);
}
};
/**
* Class SPECCTRA_DB
* holds a DSN data tree, usually coming from a DSN file.
*/
class
SPECCTRA_DB
{
FILE
*
fp
;
LEXER
*
lexer
;
ELEM
*
tree
;
FILE
*
fp
;
/**
...
...
@@ -164,26 +200,311 @@ class SPECCTRA_DB
*/
void
print
(
const
char
*
fmt
,
...
);
/**
* Function nextTok
* returns the next token from the lexer.
*/
DSN_T
nextTok
();
void
expecting
(
DSN_T
)
throw
(
IOError
);
void
expecting
(
const
wxChar
*
text
)
throw
(
IOError
);
void
doPCB
(
ELEM
*
growth
)
throw
(
IOError
);
void
doPARSER
(
ELEM
*
growth
)
throw
(
IOError
);
void
doRESOLUTION
(
ELEM
*
growth
)
throw
(
IOError
);
public
:
SPECCTRA_DB
(
FILE
*
aFile
)
:
fp
(
aFile
)
SPECCTRA_DB
()
{
lexer
=
0
;
tree
=
0
;
fp
=
0
;
}
~
SPECCTRA_DB
()
{
delete
lexer
;
delete
tree
;
if
(
fp
)
fclose
(
fp
);
}
/**
* Function Load
* is a recursive descent parser for a DSN file.
* @param filename The name of the dsn file to load.
* @throw IOError if there is a lexer or parser error.
*/
void
Load
(
const
wxString
&
filename
)
throw
(
IOError
);
void
ThrowIOError
(
const
wxChar
*
fmt
,
...
)
throw
(
IOError
);
/**
* Function Export
* writes the given BOARD out as a SPECTRA DSN format file.
* @param aBoard The BOARD to save.
*/
void
Export
(
BOARD
*
aBoard
);
};
void
SPECCTRA_DB
::
ThrowIOError
(
const
wxChar
*
fmt
,
...
)
throw
(
IOError
)
{
wxString
errText
;
va_list
args
;
va_start
(
args
,
fmt
);
errText
.
PrintfV
(
fmt
,
args
);
va_end
(
args
);
throw
IOError
(
errText
);
}
void
SPECCTRA_DB
::
expecting
(
DSN_T
aTok
)
throw
(
IOError
)
{
wxString
errText
(
_
(
"Expecting"
)
);
errText
<<
wxT
(
" "
)
<<
lexer
->
GetTokenText
(
aTok
);
lexer
->
ThrowIOError
(
errText
,
lexer
->
CurOffset
()
);
}
void
SPECCTRA_DB
::
expecting
(
const
wxChar
*
text
)
throw
(
IOError
)
{
wxString
errText
(
_
(
"Expecting"
)
);
errText
<<
wxT
(
" '"
)
<<
text
<<
wxT
(
"'"
);
lexer
->
ThrowIOError
(
errText
,
lexer
->
CurOffset
()
);
}
DSN_T
SPECCTRA_DB
::
nextTok
()
{
return
lexer
->
NextTok
();
}
void
SPECCTRA_DB
::
Load
(
const
wxString
&
filename
)
throw
(
IOError
)
{
wxFFile
file
(
filename
.
c_str
()
);
if
(
!
file
.
IsOpened
()
)
{
ThrowIOError
(
_
(
"Unable to open file
\"
%s
\"
"
),
filename
.
GetData
()
);
}
delete
lexer
;
lexer
=
0
;
lexer
=
new
LEXER
(
file
.
fp
(),
filename
);
if
(
nextTok
()
!=
T_LEFT
)
expecting
(
T_LEFT
);
if
(
nextTok
()
!=
T_pcb
)
expecting
(
T_pcb
);
tree
=
new
ELEM
(
T_pcb
);
doPCB
(
tree
);
}
void
SPECCTRA_DB
::
doPCB
(
ELEM
*
growth
)
throw
(
IOError
)
{
ELEM
*
child
;
DSN_T
tok
=
nextTok
();
switch
(
tok
)
{
case
T_SYMBOL
:
case
T_STRING
:
break
;
default
:
expecting
(
T_STRING
);
}
while
(
(
tok
=
nextTok
())
!=
T_EOF
)
{
if
(
tok
!=
T_LEFT
)
expecting
(
T_LEFT
);
tok
=
nextTok
();
switch
(
tok
)
{
case
T_parser
:
child
=
new
ELEM
(
T_parser
);
growth
->
Append
(
child
);
doPARSER
(
child
);
break
;
case
T_unit
:
child
=
new
ELEM
(
T_unit
);
growth
->
Append
(
child
);
break
;
case
T_resolution
:
child
=
new
ELEM
(
T_resolution
);
growth
->
Append
(
child
);
doRESOLUTION
(
child
);
break
;
case
T_structure
:
case
T_placement
:
case
T_library
:
break
;
default
:
expecting
(
wxT
(
"parser, unit, resolution, or structure"
)
);
}
}
}
void
SPECCTRA_DB
::
doPARSER
(
ELEM
*
growth
)
throw
(
IOError
)
{
DSN_T
tok
;
while
(
(
tok
=
nextTok
())
!=
T_RIGHT
)
{
if
(
tok
!=
T_LEFT
)
expecting
(
T_LEFT
);
tok
=
nextTok
();
switch
(
tok
)
{
case
T_string_quote
:
tok
=
nextTok
();
if
(
tok
!=
T_QUOTE_DEF
)
expecting
(
T_QUOTE_DEF
);
lexer
->
SetStringDelimiter
(
(
unsigned
char
)
*
lexer
->
CurText
()
);
break
;
case
T_space_in_quoted_tokens
:
tok
=
nextTok
();
if
(
tok
!=
T_on
&&
tok
!=
T_off
)
expecting
(
_
(
"on or off"
)
);
lexer
->
SetSpaceInQuotedTokens
(
tok
==
T_on
);
break
;
case
T_host_cad
:
tok
=
nextTok
();
if
(
tok
!=
T_STRING
&&
tok
!=
T_SYMBOL
)
expecting
(
T_SYMBOL
);
// @todo
break
;
case
T_host_version
:
tok
=
nextTok
();
if
(
tok
!=
T_STRING
&&
tok
!=
T_SYMBOL
)
expecting
(
T_SYMBOL
);
// @todo
break
;
case
T_constant
:
tok
=
nextTok
();
if
(
tok
!=
T_STRING
&&
tok
!=
T_SYMBOL
)
expecting
(
T_SYMBOL
);
tok
=
nextTok
();
if
(
tok
!=
T_STRING
&&
tok
!=
T_SYMBOL
)
expecting
(
T_SYMBOL
);
// @todo
break
;
case
T_write_resolution
:
// [(writee_resolution {<character> <positive_integer >})]
while
(
(
tok
=
nextTok
())
!=
T_RIGHT
)
{
if
(
tok
!=
T_SYMBOL
)
expecting
(
T_SYMBOL
);
tok
=
nextTok
();
if
(
tok
!=
T_NUMBER
)
expecting
(
T_NUMBER
);
// @todo
}
continue
;
// we ate the T_RIGHT
case
T_routes_include
:
// [(routes_include {[testpoint | guides | image_conductor]})]
while
(
(
tok
=
nextTok
())
!=
T_RIGHT
)
{
switch
(
tok
)
{
case
T_testpoint
:
case
T_guide
:
case
T_image_conductor
:
// @todo
break
;
default
:
expecting
(
_
(
"testpoint, guides, or image_conductor"
)
);
}
}
continue
;
// we ate the T_RIGHT
case
T_wires_include
:
// [(wires_include testpoint)]
tok
=
nextTok
();
if
(
tok
!=
T_testpoint
)
expecting
(
T_testpoint
);
// @todo
break
;
case
T_case_sensitive
:
tok
=
nextTok
();
if
(
tok
!=
T_on
&&
tok
!=
T_off
)
expecting
(
_
(
"on or off"
)
);
// @todo
break
;
case
T_via_rotate_first
:
// [(via_rotate_first [on | off])]
tok
=
nextTok
();
if
(
tok
!=
T_on
&&
tok
!=
T_off
)
expecting
(
_
(
"on or off"
)
);
// @todo
break
;
default
:
expecting
(
wxT
(
"parser_descriptor contents"
)
);
}
tok
=
nextTok
();
if
(
tok
!=
T_RIGHT
)
expecting
(
T_RIGHT
);
}
}
void
SPECCTRA_DB
::
doRESOLUTION
(
ELEM
*
growth
)
throw
(
IOError
)
{
DSN_T
tok
=
nextTok
();
switch
(
tok
)
{
case
T_inch
:
case
T_mil
:
case
T_cm
:
case
T_mm
:
case
T_um
:
// @todo
break
;
default
:
expecting
(
wxT
(
"inch, mil, cm, mm, or um"
)
);
}
tok
=
nextTok
();
if
(
tok
!=
T_NUMBER
)
expecting
(
T_NUMBER
);
tok
=
nextTok
();
if
(
tok
!=
T_RIGHT
)
expecting
(
T_RIGHT
);
}
void
SPECCTRA_DB
::
print
(
const
char
*
fmt
,
...
)
{
...
...
@@ -210,15 +531,36 @@ using namespace DSN;
int
main
(
int
argc
,
char
**
argv
)
{
PARENT
parent
(
T_pcb
);
#if 0
ELEM parent( T_pcb );
PARENT
*
child
=
new
PARENT
(
T_absolute
);
ELEM* child = new ELEM
( T_absolute );
parent.Append( child );
parent
.
At
(
0
)
->
Test
();
parent
[0]
->Test();
child->Append( new ELEM( T_absolute ) );
#else
wxString
filename
(
wxT
(
"/tmp/fpcroute/Sample_1sided/demo_1sided.dsn"
)
);
// wxString filename( wxT("/tmp/testdesigns/test.dsn") );
SPECCTRA_DB
db
;
try
{
db
.
Load
(
filename
);
}
catch
(
IOError
ioe
)
{
printf
(
"%s
\n
"
,
CONV_TO_UTF8
(
ioe
.
errorText
)
);
exit
(
1
);
}
printf
(
"loaded OK
\n
"
);
#endif
}
...
...
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