Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
8cfc4bfb
Commit
8cfc4bfb
authored
Jan 18, 1995
by
Guido van Rossum
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
initial version
parent
84fa5ecf
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
905 additions
and
0 deletions
+905
-0
Tools/bgen/bgen/bgen.py
Tools/bgen/bgen/bgen.py
+7
-0
Tools/bgen/bgen/bgenGenerator.py
Tools/bgen/bgen/bgenGenerator.py
+173
-0
Tools/bgen/bgen/bgenGeneratorGroup.py
Tools/bgen/bgen/bgenGeneratorGroup.py
+35
-0
Tools/bgen/bgen/bgenModule.py
Tools/bgen/bgen/bgenModule.py
+69
-0
Tools/bgen/bgen/bgenObjectDefinition.py
Tools/bgen/bgen/bgenObjectDefinition.py
+130
-0
Tools/bgen/bgen/bgenOutput.py
Tools/bgen/bgen/bgenOutput.py
+129
-0
Tools/bgen/bgen/bgenType.py
Tools/bgen/bgen/bgenType.py
+362
-0
No files found.
Tools/bgen/bgen/bgen.py
0 → 100644
View file @
8cfc4bfb
"Export everything in the various bgen submodules."
from
bgenType
import
*
from
bgenOutput
import
*
from
bgenGenerator
import
*
from
bgenModule
import
*
from
bgenObjectDefinition
import
*
Tools/bgen/bgen/bgenGenerator.py
0 → 100644
View file @
8cfc4bfb
from
bgenOutput
import
*
from
bgenType
import
*
Error
=
"bgenGenerator.Error"
# Strings to specify argument transfer modes in generator calls
IN
=
"in"
OUT
=
"out"
INOUT
=
IN_OUT
=
"in-out"
class
Generator
:
# XXX There are some funny things with the argument list.
# XXX It would be better to get rid of this and require
# XXX each argument to be a type object or a tuple of the form
# XXX (inoutmode, typeobject, argumentname)
# XXX or possibly even a Variable() instance...
def
__init__
(
self
,
*
argumentList
):
apply
(
self
.
parseArguments
,
argumentList
)
self
.
prefix
=
"XXX"
# Will be changed by setprefix() call
self
.
objecttype
=
"object"
# Type of _self argument to function
self
.
itselftype
=
None
# Type of _self->ob_itself, if defined
def
setprefix
(
self
,
prefix
):
self
.
prefix
=
prefix
def
setselftype
(
self
,
selftype
,
itselftype
):
self
.
objecttype
=
selftype
self
.
itselftype
=
itselftype
def
parseArguments
(
self
,
returnType
,
name
,
*
argumentList
):
if
returnType
:
self
.
rv
=
Variable
(
returnType
,
"_rv"
,
OutMode
)
else
:
self
.
rv
=
None
self
.
name
=
name
self
.
argumentList
=
[]
if
self
.
rv
:
self
.
argumentList
.
append
(
rv
)
self
.
parseArgumentList
(
argumentList
)
def
parseArgumentList
(
self
,
argumentList
):
from
types
import
*
iarg
=
0
for
arg
in
argumentList
:
# Arguments can either be:
# - a type
# - a tuple (type, [name, [mode]])
# - a variable
iarg
=
iarg
+
1
if
hasattr
(
arg
,
'typeName'
):
arg
=
Variable
(
arg
)
elif
type
(
arg
)
==
TupleType
:
arg
=
apply
(
Variable
,
arg
)
if
arg
.
name
is
None
:
arg
.
name
=
"_arg%d"
%
iarg
self
.
argumentList
.
append
(
arg
)
def
reference
(
self
,
name
=
None
):
if
name
is
None
:
name
=
self
.
name
Output
(
"{
\
"
%s
\
"
, (PyCFunction)%s_%s, 1},"
,
name
,
self
.
prefix
,
self
.
name
)
def
generate
(
self
):
self
.
functionheader
()
self
.
declarations
()
self
.
getargs
()
self
.
callit
()
self
.
checkit
()
self
.
returnvalue
()
self
.
functiontrailer
()
def
functionheader
(
self
):
Output
()
Output
(
"static PyObject *%s_%s(_self, _args)"
,
self
.
prefix
,
self
.
name
)
IndentLevel
()
Output
(
"%s *_self;"
,
self
.
objecttype
)
Output
(
"PyObject *_args;"
)
DedentLevel
()
OutLbrace
()
def
declarations
(
self
):
for
arg
in
self
.
argumentList
:
arg
.
declare
()
def
getargs
(
self
):
fmt
=
""
lst
=
""
for
arg
in
self
.
argumentList
:
if
arg
.
flags
==
SelfMode
:
continue
if
arg
.
mode
in
(
InMode
,
InOutMode
):
fmt
=
fmt
+
arg
.
getargsFormat
()
lst
=
lst
+
", "
+
arg
.
getargsArgs
()
Output
(
"if (!PyArg_ParseTuple(_args,
\
"
%s
\
"
%s))"
,
fmt
,
lst
)
IndentLevel
()
Output
(
"return NULL;"
)
DedentLevel
()
for
arg
in
self
.
argumentList
:
if
arg
.
flags
==
SelfMode
:
continue
if
arg
.
mode
in
(
InMode
,
InOutMode
):
arg
.
getargsCheck
()
def
callit
(
self
):
args
=
""
for
arg
in
self
.
argumentList
:
if
arg
is
self
.
rv
:
continue
s
=
arg
.
passArgument
()
if
args
:
s
=
", "
+
s
args
=
args
+
s
if
self
.
rv
:
Output
(
"%s = %s(%s);"
,
self
.
rv
.
name
,
self
.
name
,
args
)
else
:
Output
(
"%s(%s);"
,
self
.
name
,
args
)
def
checkit
(
self
):
for
arg
in
self
.
argumentList
:
arg
.
errorCheck
()
def
returnvalue
(
self
):
fmt
=
""
lst
=
""
for
arg
in
self
.
argumentList
:
if
not
arg
:
continue
if
arg
.
flags
==
ErrorMode
:
continue
if
arg
.
mode
in
(
OutMode
,
InOutMode
):
fmt
=
fmt
+
arg
.
mkvalueFormat
()
lst
=
lst
+
", "
+
arg
.
mkvalueArgs
()
if
fmt
==
""
:
Output
(
"Py_INCREF(Py_None);"
)
Output
(
"return Py_None;"
);
else
:
Output
(
"return Py_BuildValue(
\
"
%s
\
"
%s);"
,
fmt
,
lst
)
def
functiontrailer
(
self
):
OutRbrace
()
class
ManualGenerator
(
Generator
):
def
__init__
(
self
,
name
,
body
):
self
.
name
=
name
self
.
body
=
body
def
definition
(
self
):
self
.
functionheader
()
Output
(
"%s"
,
self
.
body
)
self
.
functiontrailer
()
def
_test
():
void
=
None
eggs
=
Generator
(
void
,
"eggs"
,
Variable
(
stringptr
,
'cmd'
),
Variable
(
int
,
'x'
),
Variable
(
double
,
'y'
,
InOutMode
),
Variable
(
int
,
'status'
,
ErrorMode
),
)
eggs
.
setprefix
(
"spam"
)
print
"/* START */"
eggs
.
generate
()
if
__name__
==
"__main__"
:
_test
()
Tools/bgen/bgen/bgenGeneratorGroup.py
0 → 100644
View file @
8cfc4bfb
from
bgenOutput
import
*
class
GeneratorGroup
:
def
__init__
(
self
,
prefix
):
self
.
prefix
=
prefix
self
.
generators
=
[]
def
add
(
self
,
g
):
g
.
setprefix
(
self
.
prefix
)
self
.
generators
.
append
(
g
)
def
generate
(
self
):
for
g
in
self
.
generators
:
g
.
generate
()
Output
()
Output
(
"static struct methodlist %s_methods[] = {"
,
self
.
prefix
)
IndentLevel
()
for
g
in
self
.
generators
:
g
.
reference
()
Output
(
"{NULL, NULL, 0}"
)
DedentLevel
()
Output
(
"};"
)
def
_test
():
from
bgenGenerator
import
Generator
group
=
GeneratorGroup
(
"spam"
)
eggs
=
Generator
(
void
,
"eggs"
)
group
.
add
(
eggs
)
print
"/* START */"
group
.
generate
()
if
__name__
==
"__main__"
:
_test
()
Tools/bgen/bgen/bgenModule.py
0 → 100644
View file @
8cfc4bfb
from
bgenOutput
import
*
from
bgenGeneratorGroup
import
GeneratorGroup
class
Module
(
GeneratorGroup
):
def
__init__
(
self
,
name
,
prefix
=
None
,
includestuff
=
None
,
initstuff
=
None
):
GeneratorGroup
.
__init__
(
self
,
prefix
or
name
)
self
.
name
=
name
self
.
includestuff
=
includestuff
self
.
initstuff
=
initstuff
def
addobject
(
self
,
od
):
self
.
generators
.
append
(
od
)
def
generate
(
self
):
OutHeader1
(
"Module "
+
self
.
name
)
Output
(
"#include <Python.h>"
)
Output
()
if
self
.
includestuff
:
Output
()
Output
(
"%s"
,
self
.
includestuff
)
self
.
declareModuleVariables
()
GeneratorGroup
.
generate
(
self
)
Output
()
Output
(
"void init%s()"
,
self
.
name
)
OutLbrace
()
Output
(
"object *m;"
)
Output
(
"object *d;"
)
Output
()
if
self
.
initstuff
:
Output
(
"%s"
,
self
.
initstuff
)
Output
()
Output
(
"m = initmodule(
\
"
%s
\
"
, %s_methods);"
,
self
.
name
,
self
.
prefix
)
Output
(
"d = getmoduledict(m);"
)
self
.
createModuleVariables
()
OutRbrace
()
OutHeader1
(
"End module "
+
self
.
name
)
def
declareModuleVariables
(
self
):
self
.
errorname
=
self
.
prefix
+
"_Error"
Output
(
"static object *%s;"
,
self
.
errorname
)
def
createModuleVariables
(
self
):
Output
(
"""if ((%s = newstringobject("%s.Error")) == NULL ||"""
,
self
.
errorname
,
self
.
name
)
Output
(
""" dictinsert(d, "Error", %s) != 0)"""
,
self
.
errorname
)
Output
(
"""
\
t
fatal("can't initialize %s.Error");"""
,
self
.
name
)
def
_test
():
from
bgenGenerator
import
Generator
m
=
Module
(
"spam"
,
""
,
"#include <stdio.h>"
)
g
=
Generator
(
None
,
"bacon"
)
m
.
add
(
g
)
m
.
generate
()
if
__name__
==
"__main__"
:
_test
()
Tools/bgen/bgen/bgenObjectDefinition.py
0 → 100644
View file @
8cfc4bfb
from
bgenOutput
import
*
from
bgenGeneratorGroup
import
GeneratorGroup
class
ObjectDefinition
(
GeneratorGroup
):
def
__init__
(
self
,
name
,
prefix
,
itselftype
):
import
string
GeneratorGroup
.
__init__
(
self
,
prefix
or
name
)
self
.
name
=
name
self
.
itselftype
=
itselftype
self
.
objecttype
=
name
+
'Object'
self
.
typename
=
self
.
prefix
+
'_'
+
\
string
.
upper
(
name
[:
1
])
+
\
string
.
lower
(
name
[
1
:])
+
'_Type'
def
add
(
self
,
g
):
g
.
setselftype
(
self
.
objecttype
,
self
.
itselftype
)
GeneratorGroup
.
add
(
self
,
g
)
def
reference
(
self
):
# In case we are referenced from a module
pass
def
generate
(
self
):
# XXX This should use long strings and %(varname)s substitution!
OutHeader2
(
"Object type "
+
self
.
name
)
Output
(
"staticforward PyTypeObject %s;"
,
self
.
typename
)
Output
()
Output
(
"#define is_%sobject(x) ((x)->ob_type == %s)"
,
self
.
name
,
self
.
typename
)
Output
()
Output
(
"typedef struct {"
)
IndentLevel
()
Output
(
"OB_HEAD"
)
Output
(
"%s ob_itself;"
,
self
.
itselftype
)
DedentLevel
()
Output
(
"} %s;"
,
self
.
objecttype
)
Output
()
Output
(
"static %s *new%s(itself)"
,
self
.
objecttype
,
self
.
objecttype
)
IndentLevel
()
Output
(
"%s itself;"
,
self
.
itselftype
)
DedentLevel
()
OutLbrace
()
Output
(
"%s *it;"
,
self
.
objecttype
)
Output
(
"it = PyObject_NEW(%s, &%s);"
,
self
.
objecttype
,
self
.
typename
)
Output
(
"if (it == NULL) return NULL;"
)
Output
(
"it->ob_itself = itself;"
)
Output
(
"return it;"
)
OutRbrace
()
Output
()
Output
(
"static void %s_dealloc(self)"
,
self
.
prefix
)
IndentLevel
()
Output
(
"%s *self;"
,
self
.
objecttype
)
DedentLevel
()
OutLbrace
()
## Output("if (self->ob_itself != NULL)")
## OutLbrace()
## self.outputFreeIt("self->ob_itself")
## OutRbrace()
Output
(
"DEL(self);"
)
OutRbrace
()
Output
()
## Output("static int %s_converter(p_itself, p_it)", self.prefix)
## IndentLevel()
## Output("%s *p_itself;", self.itselftype)
## Output("%s **p_it;", self.objecttype)
## DedentLevel()
## OutLbrace()
## Output("if (**p_it == NULL)")
## OutLbrace()
## Output("*p_it = new%s(*p_itself);", self.objecttype)
## OutRbrace()
## Output("else")
## OutLbrace()
## Output("*p_itself = (*p_it)->ob_itself;")
## OutRbrace()
## Output("return 1;")
## OutRbrace()
## Output()
GeneratorGroup
.
generate
(
self
)
self
.
outputGetattr
()
self
.
outputSetattr
()
Output
(
"static PyTypeObject %s = {"
,
self
.
typename
)
IndentLevel
()
Output
(
"PyObject_HEAD_INIT(&PyType_Type)"
)
Output
(
"0, /*ob_size*/"
)
Output
(
"
\
"
%s
\
"
, /*tp_name*/"
,
self
.
name
)
Output
(
"sizeof(%s), /*tp_basicsize*/"
,
self
.
objecttype
)
Output
(
"0, /*tp_itemsize*/"
)
Output
(
"/* methods */"
)
Output
(
"(destructor) %s_dealloc, /*tp_dealloc*/"
,
self
.
prefix
)
Output
(
"0, /*tp_print*/"
)
Output
(
"(getattrfunc) %s_getattr, /*tp_getattr*/"
,
self
.
prefix
)
Output
(
"(setattrfunc) %s_setattr, /*tp_setattr*/"
,
self
.
prefix
)
DedentLevel
()
Output
(
"};"
)
OutHeader2
(
"End object type "
+
self
.
name
)
def
outputFreeIt
(
self
,
name
):
Output
(
"DEL(%s); /* XXX */"
,
name
)
def
outputGetattr
(
self
):
Output
(
"static PyObject *%s_getattr(self, name)"
,
self
.
prefix
)
IndentLevel
()
Output
(
"%s *self;"
,
self
.
objecttype
)
Output
(
"char *name;"
)
DedentLevel
()
OutLbrace
()
self
.
outputGetattrBody
()
OutRbrace
()
Output
()
def
outputGetattrBody
(
self
):
Output
(
"return findmethod(self, %s_methods, name);"
,
self
.
prefix
)
def
outputSetattr
(
self
):
Output
(
"#define %s_setattr NULL"
,
self
.
prefix
)
Output
()
Tools/bgen/bgen/bgenOutput.py
0 → 100644
View file @
8cfc4bfb
"""Output primitives for the binding generator classes.
This should really be a class, but then everybody would be passing
the output object to each other. I chose for the simpler approach
of a module with a global variable. Use SetOutputFile() to change
the output file.
"""
def
SetOutputFile
(
file
=
None
):
"""Call this with an open file object to make that the output file.
Call it without arguments to reset the output file to sys.stdout.
"""
global
_File
if
file
is
None
:
import
sys
file
=
sys
.
stdout
_File
=
file
SetOutputFile
()
# Initialize _File
_Level
=
0
# Indentation level
def
GetLevel
():
""""Return the current indentation level."""
return
_Level
def
SetLevel
(
level
):
"""Set the current indentation level.
This does no type or range checking -- use at own risk.
"""
global
_Level
_Level
=
level
def
Output
(
format
=
""
,
*
args
):
"""Call this with a format string and arguments for the format.
A newline is always added. Each line in the output is indented
to the proper indentation level -- even if the result of the
format expansion contains embedded newlines. Exception: lines
beginning with '#' are not indented -- these are assumed to be
C preprprocessor lines.
"""
text
=
format
%
args
if
_Level
>
0
:
indent
=
'
\
t
'
*
_Level
import
string
lines
=
string
.
splitfields
(
text
,
'
\
n
'
)
for
i
in
range
(
len
(
lines
)):
if
lines
[
i
]
and
lines
[
i
][
0
]
!=
'#'
:
lines
[
i
]
=
indent
+
lines
[
i
]
text
=
string
.
joinfields
(
lines
,
'
\
n
'
)
_File
.
write
(
text
+
'
\
n
'
)
def
IndentLevel
(
by
=
1
):
"""Increment the indentation level by one.
When called with an argument, adds it to the indentation level.
"""
global
_Level
if
_Level
+
by
<
0
:
raise
Error
,
"indentation underflow (internal error)"
_Level
=
_Level
+
by
def
DedentLevel
(
by
=
1
):
"""Decfrement the indentation level by one.
When called with an argument, subtracts it from the indentation level.
"""
IndentLevel
(
-
by
)
def
OutLbrace
():
"""Output a '{' on a line by itself and increase the indentation level."""
Output
(
"{"
)
IndentLevel
()
def
OutRbrace
():
"""Decrease the indentation level and output a '}' on a line by itself."""
DedentLevel
()
Output
(
"}"
)
def
OutHeader
(
text
,
dash
):
"""Output a header comment using a given dash character."""
n
=
64
-
len
(
text
)
Output
()
Output
(
"/* %s %s %s */"
,
dash
*
(
n
/
2
),
text
,
dash
*
(
n
-
n
/
2
))
Output
()
def
OutHeader1
(
text
):
"""Output a level 1 header comment (uses '=' dashes)."""
OutHeader
(
text
,
"="
)
def
OutHeader2
(
text
):
"""Output a level 2 header comment (uses '-' dashes)."""
OutHeader
(
text
,
"-"
)
def
_test
():
"""Test program. Run when the module is run as a script."""
OutHeader1
(
"test bgenOutput"
)
Output
(
"""
#include <Python.h>
#include <stdio.h>
"""
)
Output
(
"main(argc, argv)"
)
IndentLevel
()
Output
(
"int argc;"
)
Output
(
"char **argv;"
)
DedentLevel
()
OutLbrace
()
Output
(
"int i;"
)
Output
()
Output
(
"""
\
/* Here are a few comment lines.
Just to test indenting multiple lines.
End of the comment lines. */
"""
)
Output
(
"for (i = 0; i < argc; i++)"
)
OutLbrace
()
Output
(
'printf("argv[%%d] = %%s
\
\
n", i, argv[i]);'
)
OutRbrace
()
Output
(
"exit(0)"
)
OutRbrace
()
OutHeader2
(
"end test"
)
if
__name__
==
'__main__'
:
_test
()
Tools/bgen/bgen/bgenType.py
0 → 100644
View file @
8cfc4bfb
"""Type and Variable classes and a modest collection of standard types."""
from
bgenOutput
import
*
# Values to represent argument transfer modes
InMode
=
1
# input-only argument
OutMode
=
2
# output-only argument
InOutMode
=
3
# input-output argument
ModeMask
=
3
# bits to keep for mode
# Special cases for mode/flags argument
# XXX This is still a mess!
SelfMode
=
4
+
InMode
# this is 'self' -- don't declare it
ReturnMode
=
8
+
OutMode
# this is the function return value
ErrorMode
=
16
+
OutMode
# this is an error status -- turn it into an exception
class
Type
:
"""Define the various things you can do with a C type.
Most methods are intended to be extended or overridden.
"""
def
__init__
(
self
,
typeName
,
fmt
):
"""Call with the C name and getargs format for the type.
Example: int = Type("int", "i")
"""
self
.
typeName
=
typeName
self
.
fmt
=
fmt
def
declare
(
self
,
name
):
"""Declare a variable of the type with a given name.
Example: int.declare('spam') prints "int spam;"
"""
Output
(
"%s %s;"
,
self
.
typeName
,
name
)
def
getargsFormat
(
self
):
"""Return the format for this type for use with [new]getargs().
Example: int.getargsFormat() returns the string "i".
"""
return
self
.
fmt
def
getargsArgs
(
self
,
name
):
"""Return an argument for use with [new]getargs().
Example: int.getargsArgs("spam") returns the string "&spam".
"""
return
"&"
+
name
def
getargsCheck
(
self
,
name
):
"""Perform any needed post-[new]getargs() checks.
This is type-dependent; the default does not check for errors.
An example would be a check for a maximum string length."""
def
passInput
(
self
,
name
):
"""Return an argument for passing a variable into a call.
Example: int.passInput("spam") returns the string "spam".
"""
return
name
def
passOutput
(
self
,
name
):
"""Return an argument for returning a variable out of a call.
Example: int.passOutput("spam") returns the string "&spam".
"""
return
"&"
+
name
def
errorCheck
(
self
,
name
):
"""Check for an error returned in the variable.
This is type-dependent; the default does not check for errors.
An example would be a check for a NULL pointer.
If an error is found, the generated routine should
raise an exception and return NULL.
XXX There should be a way to add error clean-up code.
"""
Output
(
"/* XXX no err check for %s %s */"
,
self
.
typeName
,
name
)
def
mkvalueFormat
(
self
):
"""Return the format for this type for use with mkvalue().
This is normally the same as getargsFormat() but it is
a separate function to allow future divergence.
"""
return
self
.
getargsFormat
()
def
mkvalueArgs
(
self
,
name
):
"""Return an argument for use with mkvalue().
Example: int.mkvalueArgs("spam") returns the string "spam".
"""
return
name
# A modest collection of standard C types.
void
=
None
short
=
Type
(
"short"
,
"h"
)
int
=
Type
(
"int"
,
"i"
)
long
=
Type
(
"long"
,
"l"
)
float
=
Type
(
"float"
,
"f"
)
double
=
Type
(
"double"
,
"d"
)
stringptr
=
Type
(
"char*"
,
"s"
)
char
=
Type
(
"char"
,
"c"
)
# Some Python related types.
objectptr
=
Type
(
"object*"
,
"O"
)
stringobjectptr
=
Type
(
"stringobject*"
,
"S"
)
# Etc.
# Buffers are character arrays that may contain null bytes.
# Their length is either Fixed or Sized (i.e. given by a separate argument).
class
SizedInputBuffer
:
"Sized input buffer -- buffer size is an input parameter"
def
__init__
(
self
,
size
):
self
.
size
=
size
def
declare
(
self
,
name
):
Output
(
"char *%s;"
,
name
)
Output
(
"int %s__len__;"
,
name
)
def
getargsFormat
(
self
):
return
"s#"
def
getargsArgs
(
self
,
name
):
return
"%s, %s__len__"
%
(
name
,
name
)
def
getargsCheck
(
self
,
name
):
pass
def
passInput
(
self
,
name
):
return
"%s, %s__len__"
%
(
name
,
name
)
class
FixedInputBuffer
(
SizedInputBuffer
):
"Fixed input buffer -- buffer size is a constant"
def
getargsCheck
(
self
,
name
):
Output
(
"if (%s__len__ != %s)"
,
name
,
str
(
self
.
size
))
IndentLevel
()
Output
(
'err_setstr(TypeError, "bad string length");'
)
DedentLevel
()
def
passInput
(
self
,
name
):
return
name
class
SizedOutputBuffer
:
"Sized output buffer -- buffer size is an input-output parameter"
def
__init__
(
self
,
maxsize
):
self
.
maxsize
=
maxsize
def
declare
(
self
,
name
):
Output
(
"char %s[%s];"
,
name
,
str
(
self
.
maxsize
))
Output
(
"int %s__len__ = %s;"
,
name
,
str
(
self
.
maxsize
))
def
passOutput
(
self
,
name
):
return
"%s, &%s__len__"
%
(
name
,
name
)
def
errorCheck
(
self
,
name
):
pass
def
mkvalueFormat
(
self
):
return
"s#"
def
mkvalueArgs
(
self
,
name
):
return
"%s, %s__len__"
%
(
name
,
name
)
class
FixedOutputBuffer
:
"Fixed output buffer -- buffer size is a constant"
def
__init__
(
self
,
size
):
self
.
size
=
size
def
declare
(
self
,
name
):
Output
(
"char %s[%s];"
,
name
,
str
(
self
.
size
))
def
passOutput
(
self
,
name
):
return
name
def
errorCheck
(
self
,
name
):
pass
def
mkvalueFormat
(
self
):
return
"s#"
def
mkvalueArgs
(
self
,
name
):
return
"%s, %s"
%
(
name
,
str
(
self
.
size
))
# Strings are character arrays terminated by a null byte.
# For input, this is covered by stringptr.
# For output, there are again two variants: Fixed (size is a constant
# given in the documentation) or Sized (size is given by a variable).
# (Note that this doesn't cover output parameters in which a string
# pointer is returned.)
class
SizedOutputString
:
"Null-terminated output string -- buffer size is an input parameter"
def
__init__
(
self
,
bufsize
):
self
.
bufsize
=
bufsize
def
declare
(
self
,
name
):
Output
(
"char %s[%s];"
,
name
,
str
(
self
.
bufsize
))
def
passOutput
(
self
,
name
):
return
"%s, %s"
%
(
name
,
str
(
self
.
bufsize
))
def
errorCheck
(
self
,
name
):
pass
def
mkvalueFormat
(
self
):
return
"s"
def
mkvalueArgs
(
self
,
name
):
return
name
class
FixedOutputString
(
SizedOutputString
):
"Null-terminated output string -- buffer size is a constant"
def
passOutput
(
self
,
name
):
return
name
class
StructureByValue
:
"Structure passed by value -- mapped to a Python string (for now)"
def
__init__
(
self
,
typeName
):
self
.
typeName
=
typeName
def
declare
(
self
,
name
):
n
=
len
(
self
.
typeName
)
Output
(
"%-*s %s;"
,
n
,
self
.
typeName
,
name
)
Output
(
"%-*s*%s__str__;"
,
n
,
"char"
,
name
)
Output
(
"%-*s %s__len__;"
,
n
,
"int"
,
name
)
def
getargsFormat
(
self
):
return
"s#"
def
getargsArgs
(
self
,
name
):
return
"&%s__str__, &%s__len__"
%
(
name
,
name
)
def
getargsCheck
(
self
,
name
):
Output
(
"if (%s__len__ != sizeof %s)"
,
name
,
name
)
IndentLevel
()
Output
(
'err_setstr(TypeError, "bad structure length");'
)
DedentLevel
()
Output
(
"memcpy(&%s, %s__str__, %s__len__);"
,
name
,
name
,
name
)
def
passInput
(
self
,
name
):
return
"%s"
%
name
def
passOutput
(
self
,
name
):
return
"&%s"
%
name
def
errorCheck
(
self
,
name
):
pass
def
mkvalueFormat
(
self
):
return
"s#"
def
mkvalueArgs
(
self
,
name
):
return
"(char *)&%s, (int)sizeof %s"
%
(
name
,
name
)
class
StructureByAddress
(
StructureByValue
):
def
passInput
(
self
,
name
):
return
"&%s"
%
name
class
Variable
:
"""A Variable holds a type, a name, a transfer mode and flags.
Most of its methods call the correponding type method with the
variable name.
"""
def
__init__
(
self
,
type
,
name
=
None
,
flags
=
InMode
):
"""Call with a type, a name and flags.
If name is None, it muse be set later.
flags defaults to InMode.
"""
self
.
type
=
type
self
.
name
=
name
self
.
flags
=
flags
self
.
mode
=
flags
&
ModeMask
def
declare
(
self
):
"""Declare the variable if necessary.
If it is "self", it is not declared.
"""
if
self
.
flags
!=
SelfMode
:
self
.
type
.
declare
(
self
.
name
)
def
getargsFormat
(
self
):
"""Call the type's getargsFormatmethod."""
return
self
.
type
.
getargsFormat
()
def
getargsArgs
(
self
):
"""Call the type's getargsArgsmethod."""
return
self
.
type
.
getargsArgs
(
self
.
name
)
def
getargsCheck
(
self
):
return
self
.
type
.
getargsCheck
(
self
.
name
)
def
passArgument
(
self
):
"""Return the string required to pass the variable as argument.
For "in" arguments, return the variable name.
For "out" and "in out" arguments,
return its name prefixed with "&".
"""
if
self
.
mode
==
InMode
:
return
self
.
type
.
passInput
(
self
.
name
)
if
self
.
mode
in
(
OutMode
,
InOutMode
):
return
self
.
type
.
passOutput
(
self
.
name
)
# XXX Shouldn't get here
return
"/*mode?*/"
+
self
.
type
.
passInput
(
self
.
name
)
def
errorCheck
(
self
):
"""Check for an error if necessary.
This only generates code if the variable's mode is ErrorMode.
"""
if
self
.
flags
==
ErrorMode
:
self
.
type
.
errorCheck
(
self
.
name
)
def
mkvalueFormat
(
self
):
"""Call the type's mkvalueFormatmethod."""
return
self
.
type
.
mkvalueFormat
()
def
mkvalueArgs
(
self
):
"""Call the type's mkvalueArgs method."""
return
self
.
type
.
mkvalueArgs
(
self
.
name
)
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