Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
David MacDonald
purr-data
Commits
81cd906b
Commit
81cd906b
authored
Feb 18, 2017
by
Albert Gräf
Browse files
Backport IOhannes' and Miller's loader fixes from vanilla. Fixes #266.
parent
5f809c02
Changes
3
Hide whitespace changes
Inline
Side-by-side
pd/src/m_class.c
View file @
81cd906b
...
...
@@ -613,9 +613,6 @@ int pd_setloadingabstraction(t_symbol *sym);
doesn't know. Pd tries to load it as an extern, then as an abstraction. */
void
new_anything
(
void
*
dummy
,
t_symbol
*
s
,
int
argc
,
t_atom
*
argv
)
{
t_pd
*
current
;
int
fd
;
char
dirbuf
[
FILENAME_MAX
],
*
nameptr
;
if
(
tryingalready
)
return
;
newest
=
0
;
class_loadsym
=
s
;
...
...
@@ -627,25 +624,6 @@ void new_anything(void *dummy, t_symbol *s, int argc, t_atom *argv)
return
;
}
class_loadsym
=
0
;
current
=
s__X
.
s_thing
;
if
((
fd
=
canvas_open
(
canvas_getcurrent
(),
s
->
s_name
,
".pd"
,
dirbuf
,
&
nameptr
,
FILENAME_MAX
,
0
))
>=
0
||
(
fd
=
canvas_open
(
canvas_getcurrent
(),
s
->
s_name
,
".pat"
,
dirbuf
,
&
nameptr
,
FILENAME_MAX
,
0
))
>=
0
)
{
close
(
fd
);
if
(
!
pd_setloadingabstraction
(
s
))
{
canvas_setargs
(
argc
,
argv
);
binbuf_evalfile
(
gensym
(
nameptr
),
gensym
(
dirbuf
));
canvas_initbang
((
t_canvas
*
)(
s__X
.
s_thing
));
/* JMZ*/
if
(
s__X
.
s_thing
!=
current
)
canvas_popabstraction
((
t_canvas
*
)(
s__X
.
s_thing
));
canvas_setargs
(
0
,
0
);
}
else
error
(
"%s: can't load abstraction within itself
\n
"
,
s
->
s_name
);
}
else
newest
=
0
;
}
t_symbol
s_pointer
=
{
"pointer"
,
0
,
0
};
...
...
pd/src/s_loader.c
View file @
81cd906b
...
...
@@ -2,20 +2,20 @@
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
#ifdef
HAVE_LIBDL
#if
def
ined(
HAVE_LIBDL
) || defined(__FreeBSD__)
#include <dlfcn.h>
#endif
#ifdef UNISTD
#ifdef
HAVE_
UNISTD
_H
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#endif
#ifdef
MSW
#ifdef
_WIN32
#include <io.h>
#include <windows.h>
#endif
#ifdef __APPLE__
#include <mach-o/dyld.h>
#include <mach-o/dyld.h>
#endif
#include <string.h>
#include "m_pd.h"
...
...
@@ -24,6 +24,7 @@
#include <sys/stat.h>
#ifdef _MSC_VER
/* This is only for Microsoft's compiler, not cygwin, e.g. */
#define snprintf sprintf_s
#define stat _stat
#endif
typedef
void
(
*
t_xxx
)(
void
);
...
...
@@ -36,9 +37,7 @@ objects. The specific name is the letter b, l, d, or m for BSD, linux,
darwin, or microsoft, followed by a more specific string, either "fat" for
a fat binary or an indication of the instruction set. */
#ifdef __FreeBSD__
static
char
sys_dllextent
[]
=
".b_i386"
,
sys_dllextent2
[]
=
".pd_freebsd"
;
#elif defined(__linux__) || defined(__FreeBSD_kernel__) || defined(__GNU__)
#if defined(__linux__) || defined(__FreeBSD_kernel__) || defined(__GNU__) || defined(__FreeBSD__)
static
char
sys_dllextent2
[]
=
".pd_linux"
;
# ifdef __x86_64__
static
char
sys_dllextent
[]
=
".l_ia64"
;
// this should be .l_x86_64 or .l_amd64
...
...
@@ -69,7 +68,7 @@ typedef struct _loadedlist
}
t_loadlist
;
static
t_loadlist
*
sys_loaded
;
int
sys_onloadlist
(
char
*
classname
)
/* return true if already loaded */
int
sys_onloadlist
(
const
char
*
classname
)
/* return true if already loaded */
{
t_symbol
*
s
=
gensym
(
classname
);
t_loadlist
*
ll
;
...
...
@@ -79,7 +78,8 @@ int sys_onloadlist(char *classname) /* return true if already loaded */
return
(
0
);
}
void
sys_putonloadlist
(
char
*
classname
)
/* add to list of loaded modules */
/* add to list of loaded modules */
void
sys_putonloadlist
(
const
char
*
classname
)
{
t_loadlist
*
ll
=
(
t_loadlist
*
)
getbytes
(
sizeof
(
*
ll
));
ll
->
ll_name
=
gensym
(
classname
);
...
...
@@ -90,27 +90,31 @@ void sys_putonloadlist(char *classname) /* add to list of loaded modules */
void
class_set_extern_dir
(
t_symbol
*
s
);
static
int
sys_do_load_lib
(
t_canvas
*
canvas
,
char
*
objectname
)
static
int
sys_do_load_abs
(
t_canvas
*
canvas
,
const
char
*
objectname
,
const
char
*
path
);
static
int
sys_do_load_lib
(
t_canvas
*
canvas
,
const
char
*
objectname
,
const
char
*
path
)
{
char
symname
[
MAXPDSTRING
],
filename
[
FILENAME_MAX
],
dirbuf
[
FILENAME_MAX
],
*
classname
,
*
nameptr
;
char
symname
[
MAXPDSTRING
],
filename
[
MAXPDSTRING
],
dirbuf
[
MAXPDSTRING
],
*
nameptr
,
altsymname
[
MAXPDSTRING
];
const
char
*
classname
,
*
cnameptr
;
void
*
dlobj
;
t_xxx
makeout
=
NULL
;
int
i
,
hexmunge
=
0
,
fd
;
#ifdef
MSW
#ifdef
_WIN32
HINSTANCE
ntdll
;
#endif
if
(
classname
=
strrchr
(
objectname
,
'/'
))
/* NULL-path is only used as a last resort,
but we have already tried all paths */
if
(
!
path
)
return
(
0
);
if
((
classname
=
strrchr
(
objectname
,
'/'
)))
classname
++
;
else
classname
=
objectname
;
if
(
sys_onloadlist
(
objectname
))
for
(
i
=
0
,
cnameptr
=
classname
;
i
<
MAXPDSTRING
-
7
&&
*
cnameptr
;
cnameptr
++
)
{
post
(
"%s: already loaded"
,
objectname
);
return
(
1
);
}
for
(
i
=
0
,
nameptr
=
classname
;
i
<
MAXPDSTRING
-
7
&&
*
nameptr
;
nameptr
++
)
{
char
c
=
*
nameptr
;
char
c
=
*
cnameptr
;
if
((
c
>=
'0'
&&
c
<=
'9'
)
||
(
c
>=
'A'
&&
c
<=
'Z'
)
||
(
c
>=
'a'
&&
c
<=
'z'
)
||
c
==
'_'
)
{
...
...
@@ -118,7 +122,7 @@ static int sys_do_load_lib(t_canvas *canvas, char *objectname)
i
++
;
}
/* trailing tilde becomes "_tilde" */
else
if
(
c
==
'~'
&&
nameptr
[
1
]
==
0
)
else
if
(
c
==
'~'
&&
c
nameptr
[
1
]
==
0
)
{
strcpy
(
symname
+
i
,
"_tilde"
);
i
+=
strlen
(
symname
+
i
);
...
...
@@ -137,76 +141,112 @@ static int sys_do_load_lib(t_canvas *canvas, char *objectname)
strncpy
(
symname
,
"setup_"
,
6
);
}
else
strcat
(
symname
,
"_setup"
);
#if 0
fprintf(stderr, "lib:
%s
%s\n", classname
, symname
);
fprintf(stderr, "lib: %s\n", classname);
#endif
/* try looking in the path for (objectname).(sys_dllextent) ... */
if
((
fd
=
canvas_open
(
canvas
,
objectname
,
sys_dllextent
,
dirbuf
,
&
nameptr
,
FILENAME_MAX
,
1
))
>=
0
)
if
((
fd
=
sys_trytoopenone
(
path
,
objectname
,
sys_dllextent
,
dirbuf
,
&
nameptr
,
MAXPDSTRING
,
1
))
>=
0
)
goto
gotone
;
/* same, with the more generic sys_dllextent2 */
if
((
fd
=
canvas_open
(
canvas
,
objectname
,
sys_dllextent2
,
dirbuf
,
&
nameptr
,
FILENAME_MAX
,
1
))
>=
0
)
if
((
fd
=
sys_trytoopenone
(
path
,
objectname
,
sys_dllextent2
,
dirbuf
,
&
nameptr
,
MAXPDSTRING
,
1
))
>=
0
)
goto
gotone
;
/* next try (objectname)/(classname).(sys_dllextent) ... */
strncpy
(
filename
,
objectname
,
FILENAME_MAX
);
strncpy
(
filename
,
objectname
,
MAXPDSTRING
);
filename
[
MAXPDSTRING
-
2
]
=
0
;
strcat
(
filename
,
"/"
);
strncat
(
filename
,
classname
,
FILENAME_MAX
-
strlen
(
filename
));
filename
[
FILENAME_MAX
-
1
]
=
0
;
if
((
fd
=
canvas_open
(
canvas
,
filename
,
sys_dllextent
,
dirbuf
,
&
nameptr
,
FILENAME_MAX
,
1
))
>=
0
)
strncat
(
filename
,
classname
,
MAXPDSTRING
-
strlen
(
filename
));
filename
[
MAXPDSTRING
-
1
]
=
0
;
if
((
fd
=
sys_trytoopenone
(
path
,
filename
,
sys_dllextent
,
dirbuf
,
&
nameptr
,
MAXPDSTRING
,
1
))
>=
0
)
goto
gotone
;
if
((
fd
=
canvas_open
(
canvas
,
filename
,
sys_dllextent2
,
dirbuf
,
&
nameptr
,
FILENAME_MAX
,
1
))
>=
0
)
if
((
fd
=
sys_trytoopenone
(
path
,
filename
,
sys_dllextent2
,
dirbuf
,
&
nameptr
,
MAXPDSTRING
,
1
))
>=
0
)
goto
gotone
;
#ifdef ANDROID
/* Android libs have a 'lib' prefix, '.so' suffix and don't allow ~ */
char
libname
[
MAXPDSTRING
]
=
"lib"
;
strncat
(
libname
,
objectname
,
MAXPDSTRING
-
4
);
int
len
=
strlen
(
libname
);
if
(
libname
[
len
-
1
]
==
'~'
&&
len
<
MAXPDSTRING
-
6
)
{
strcpy
(
libname
+
len
-
1
,
"_tilde"
);
}
if
((
fd
=
sys_trytoopenone
(
path
,
libname
,
".so"
,
dirbuf
,
&
nameptr
,
MAXPDSTRING
,
1
))
>=
0
)
goto
gotone
;
#endif
return
(
0
);
gotone:
close
(
fd
);
class_set_extern_dir
(
gensym
(
dirbuf
));
/* rebuild the absolute pathname */
strncpy
(
filename
,
dirbuf
,
FILENAME_MAX
);
filename
[
FILENAME_MAX
-
2
]
=
0
;
strncpy
(
filename
,
dirbuf
,
MAXPDSTRING
);
filename
[
MAXPDSTRING
-
2
]
=
0
;
strcat
(
filename
,
"/"
);
strncat
(
filename
,
nameptr
,
FILENAME_MAX
-
strlen
(
filename
));
filename
[
FILENAME_MAX
-
1
]
=
0
;
strncat
(
filename
,
nameptr
,
MAXPDSTRING
-
strlen
(
filename
));
filename
[
MAXPDSTRING
-
1
]
=
0
;
#ifdef HAVE_LIBDL
#ifdef _WIN32
{
char
dirname
[
MAXPDSTRING
],
*
s
,
*
basename
;
sys_bashfilename
(
filename
,
filename
);
/* set the dirname as DllDirectory, meaning in the path for
loading other DLLs so that dependent libraries can be included
in the same folder as the external. SetDllDirectory() needs a
minimum supported version of Windows XP SP1 for
SetDllDirectory, so WINVER must be 0x0502 */
strncpy
(
dirname
,
filename
,
MAXPDSTRING
);
s
=
strrchr
(
dirname
,
'\\'
);
basename
=
s
;
if
(
s
&&
*
s
)
*
s
=
'\0'
;
if
(
!
SetDllDirectory
(
dirname
))
error
(
"Could not set '%s' as DllDirectory(), '%s' might not load."
,
dirname
,
basename
);
/* now load the DLL for the external */
ntdll
=
LoadLibrary
(
filename
);
if
(
!
ntdll
)
{
verbose
(
1
,
"%s: couldn't load"
,
filename
);
class_set_extern_dir
(
&
s_
);
return
(
0
);
}
makeout
=
(
t_xxx
)
GetProcAddress
(
ntdll
,
symname
);
if
(
!
makeout
)
makeout
=
(
t_xxx
)
GetProcAddress
(
ntdll
,
"setup"
);
SetDllDirectory
(
NULL
);
/* reset DLL dir to nothing */
}
#elif defined(HAVE_LIBDL) || defined(__FreeBSD__)
dlobj
=
dlopen
(
filename
,
RTLD_NOW
|
RTLD_GLOBAL
);
if
(
!
dlobj
)
{
post
(
"%s: %s"
,
filename
,
dlerror
());
verbose
(
1
,
"%s: %s"
,
filename
,
dlerror
());
class_set_extern_dir
(
&
s_
);
return
(
0
);
}
makeout
=
(
t_xxx
)
dlsym
(
dlobj
,
symname
);
#endif
#ifdef MSW
sys_bashfilename
(
filename
,
filename
);
ntdll
=
LoadLibrary
(
filename
);
if
(
!
ntdll
)
{
post
(
"%s: couldn't load"
,
filename
);
class_set_extern_dir
(
&
s_
);
return
(
0
);
}
makeout
=
(
t_xxx
)
GetProcAddress
(
ntdll
,
symname
);
if
(
!
makeout
)
makeout
=
(
t_xxx
)
dlsym
(
dlobj
,
"setup"
);
#else
#warning "No dynamic loading mechanism specified, \
libdl or WIN32 required for loading externals!"
#endif
if
(
!
makeout
)
{
post
(
"load_object: Symbol
\"
%s
\"
not found"
,
symname
);
verbose
(
1
,
"load_object: Symbol
\"
%s
\"
not found"
,
symname
);
class_set_extern_dir
(
&
s_
);
return
0
;
}
(
*
makeout
)();
class_set_extern_dir
(
&
s_
);
sys_putonloadlist
(
objectname
);
return
(
1
);
}
/* linked list of loaders */
typedef
struct
loader_queue
{
loader_t
loader
;
...
...
@@ -221,7 +261,9 @@ void sys_register_loader(loader_t loader)
loader_queue_t
*
q
=
&
loaders
;
while
(
1
)
{
if
(
q
->
next
)
if
(
q
->
loader
==
loader
)
/* already loaded - nothing to do */
return
;
else
if
(
q
->
next
)
q
=
q
->
next
;
else
{
...
...
@@ -230,18 +272,78 @@ void sys_register_loader(loader_t loader)
q
->
next
->
next
=
NULL
;
break
;
}
}
}
}
int
sys_load_lib
(
t_canvas
*
canvas
,
char
*
classname
)
#include "g_canvas.h"
/* the data passed to the iter-function */
struct
_loadlib_data
{
t_canvas
*
canvas
;
const
char
*
classname
;
int
ok
;
};
int
sys_loadlib_iter
(
const
char
*
path
,
struct
_loadlib_data
*
data
)
{
int
dspstate
=
canvas_suspend_dsp
();
int
ok
=
0
;
loader_queue_t
*
q
;
for
(
q
=
&
loaders
;
q
;
q
=
q
->
next
)
if
(
ok
=
q
->
loader
(
canvas
,
classname
))
break
;
if
((
ok
=
q
->
loader
(
data
->
canvas
,
data
->
classname
,
path
)))
break
;
/* if all loaders failed, try to load as abstraction */
if
(
!
ok
)
ok
=
sys_do_load_abs
(
data
->
canvas
,
data
->
classname
,
path
);
data
->
ok
=
ok
;
return
(
ok
==
0
);
}
int
sys_load_lib
(
t_canvas
*
canvas
,
const
char
*
classname
)
{
int
dspstate
=
canvas_suspend_dsp
();
struct
_loadlib_data
data
;
data
.
canvas
=
canvas
;
data
.
ok
=
0
;
if
(
sys_onloadlist
(
classname
))
{
verbose
(
1
,
"%s: already loaded"
,
classname
);
return
(
1
);
}
/* if classname is absolute, try this first */
if
(
sys_isabsolutepath
(
classname
))
{
/* this is just copied from sys_open_absolute()
LATER avoid code duplication */
char
dirbuf
[
MAXPDSTRING
],
*
z
=
strrchr
(
classname
,
'/'
);
int
dirlen
;
if
(
!
z
)
return
(
0
);
dirlen
=
z
-
classname
;
if
(
dirlen
>
MAXPDSTRING
-
1
)
dirlen
=
MAXPDSTRING
-
1
;
strncpy
(
dirbuf
,
classname
,
dirlen
);
dirbuf
[
dirlen
]
=
0
;
data
.
classname
=
classname
+
(
dirlen
+
1
);
sys_loadlib_iter
(
dirbuf
,
&
data
);
}
data
.
classname
=
classname
;
if
(
!
data
.
ok
)
canvas_path_iterate
(
canvas
,
(
t_canvas_path_iterator
)
sys_loadlib_iter
,
&
data
);
/* if loaders failed so far, we try a last time without a PATH
* let the loaders search wherever they want */
if
(
!
data
.
ok
)
sys_loadlib_iter
(
0
,
&
data
);
if
(
data
.
ok
)
sys_putonloadlist
(
classname
);
canvas_resume_dsp
(
dspstate
);
return
ok
;
return
data
.
ok
;
}
int
sys_run_scheduler
(
const
char
*
externalschedlibname
,
...
...
@@ -250,41 +352,142 @@ int sys_run_scheduler(const char *externalschedlibname,
typedef
int
(
*
t_externalschedlibmain
)(
const
char
*
);
t_externalschedlibmain
externalmainfunc
;
char
filename
[
MAXPDSTRING
];
struct
stat
statbuf
;
snprintf
(
filename
,
sizeof
(
filename
),
"%s%s"
,
externalschedlibname
,
sys_dllextent
);
sys_bashfilename
(
filename
,
filename
);
#ifdef MSW
/* if first-choice file extent can't 'stat', go for second */
if
(
stat
(
filename
,
&
statbuf
)
<
0
)
{
snprintf
(
filename
,
sizeof
(
filename
),
"%s%s"
,
externalschedlibname
,
sys_dllextent2
);
sys_bashfilename
(
filename
,
filename
);
}
#ifdef _WIN32
{
HINSTANCE
ntdll
=
LoadLibrary
(
filename
);
if
(
!
ntdll
)
{
post
(
"%s: couldn't load external scheduler lib "
,
filename
);
fprintf
(
stderr
,
"%s: couldn't load external scheduler
\n
"
,
filename
);
error
(
"%s: couldn't load external scheduler"
,
filename
);
return
(
1
);
}
externalmainfunc
=
(
t_externalschedlibmain
)
GetProcAddress
(
ntdll
,
"main"
);
(
t_externalschedlibmain
)
GetProcAddress
(
ntdll
,
"pd_extern_sched"
);
if
(
!
externalmainfunc
)
externalmainfunc
=
(
t_externalschedlibmain
)
GetProcAddress
(
ntdll
,
"main"
);
}
#el
se
#el
if defined HAVE_LIBDL
{
void
*
dlobj
;
struct
stat
statbuf
;
/* if first-choice file extent can't 'stat', go for second */
if
(
stat
(
filename
,
&
statbuf
)
<
0
)
{
snprintf
(
filename
,
sizeof
(
filename
),
"%s%s"
,
externalschedlibname
,
sys_dllextent2
);
sys_bashfilename
(
filename
,
filename
);
}
dlobj
=
dlopen
(
filename
,
RTLD_NOW
|
RTLD_GLOBAL
);
if
(
!
dlobj
)
{
post
(
"%s: %s"
,
filename
,
dlerror
());
error
(
"%s: %s"
,
filename
,
dlerror
());
fprintf
(
stderr
,
"dlopen failed for %s: %s
\n
"
,
filename
,
dlerror
());
return
(
1
);
}
externalmainfunc
=
(
t_externalschedlibmain
)
dlsym
(
dlobj
,
"pd_extern_sched"
);
}
#else
return
(
0
);
#endif
return
((
*
externalmainfunc
)(
sys_extraflagsstring
));
if
(
externalmainfunc
)
return
((
*
externalmainfunc
)(
sys_extraflagsstring
));
else
{
fprintf
(
stderr
,
"%s: couldn't find pd_extern_sched() or main()
\n
"
,
filename
);
return
(
0
);
}
}
/* abstraction loading */
void
canvas_popabstraction
(
t_canvas
*
x
);
int
pd_setloadingabstraction
(
t_symbol
*
sym
);
extern
t_pd
*
newest
;
static
t_pd
*
do_create_abstraction
(
t_symbol
*
s
,
int
argc
,
t_atom
*
argv
)
{
/*
* TODO: check if the there is a binbuf cached for <canvas::symbol>
and use that instead. We'll have to invalidate the cache once we
are done (either with a clock_delay(0) or something else)
*/
if
(
!
pd_setloadingabstraction
(
s
))
{
const
char
*
objectname
=
s
->
s_name
;
char
dirbuf
[
MAXPDSTRING
],
classslashclass
[
MAXPDSTRING
],
*
nameptr
;
t_glist
*
glist
=
(
t_glist
*
)
canvas_getcurrent
();
t_canvas
*
canvas
=
(
t_canvas
*
)
glist_getcanvas
(
glist
);
int
fd
=
-
1
;
t_pd
*
was
=
s__X
.
s_thing
;
snprintf
(
classslashclass
,
MAXPDSTRING
,
"%s/%s"
,
objectname
,
objectname
);
if
((
fd
=
canvas_open
(
canvas
,
objectname
,
".pd"
,
dirbuf
,
&
nameptr
,
MAXPDSTRING
,
0
))
>=
0
||
(
fd
=
canvas_open
(
canvas
,
objectname
,
".pat"
,
dirbuf
,
&
nameptr
,
MAXPDSTRING
,
0
))
>=
0
||
(
fd
=
canvas_open
(
canvas
,
classslashclass
,
".pd"
,
dirbuf
,
&
nameptr
,
MAXPDSTRING
,
0
))
>=
0
)
{
close
(
fd
);
canvas_setargs
(
argc
,
argv
);
binbuf_evalfile
(
gensym
(
nameptr
),
gensym
(
dirbuf
));
if
(
s__X
.
s_thing
&&
was
!=
s__X
.
s_thing
)
canvas_popabstraction
((
t_canvas
*
)(
s__X
.
s_thing
));
else
s__X
.
s_thing
=
was
;
canvas_setargs
(
0
,
0
);
return
(
newest
);
}
/* otherwise we couldn't do it; just return 0 */
}
else
error
(
"%s: can't load abstraction within itself
\n
"
,
s
->
s_name
);
newest
=
0
;
return
(
0
);
}
/* search for abstraction; register a creator if found */
static
int
sys_do_load_abs
(
t_canvas
*
canvas
,
const
char
*
objectname
,
const
char
*
path
)
{
int
fd
;
static
t_gobj
*
abstraction_classes
=
0
;
char
dirbuf
[
MAXPDSTRING
],
classslashclass
[
MAXPDSTRING
],
*
nameptr
;
/* NULL-path is only used as a last resort,
but we have already tried all paths */
if
(
!
path
)
return
(
0
);
snprintf
(
classslashclass
,
MAXPDSTRING
,
"%s/%s"
,
objectname
,
objectname
);
if
((
fd
=
sys_trytoopenone
(
path
,
objectname
,
".pd"
,
dirbuf
,
&
nameptr
,
MAXPDSTRING
,
1
))
>=
0
||
(
fd
=
sys_trytoopenone
(
path
,
objectname
,
".pat"
,
dirbuf
,
&
nameptr
,
MAXPDSTRING
,
1
))
>=
0
||
(
fd
=
sys_trytoopenone
(
path
,
classslashclass
,
".pd"
,
dirbuf
,
&
nameptr
,
MAXPDSTRING
,
1
))
>=
0
)
{
t_class
*
c
=
0
;
close
(
fd
);
/* found an abstraction, now register it as a new pseudo-class */
class_set_extern_dir
(
gensym
(
dirbuf
));
if
((
c
=
class_new
(
gensym
(
objectname
),
(
t_newmethod
)
do_create_abstraction
,
0
,
0
,
0
,
A_GIMME
,
0
)))
{
/* store away the newly created class, maybe we will need it one day */
t_gobj
*
absclass
=
0
;
absclass
=
t_getbytes
(
sizeof
(
*
absclass
));
absclass
->
g_pd
=
c
;
absclass
->
g_next
=
abstraction_classes
;
abstraction_classes
=
absclass
;
}
class_set_extern_dir
(
&
s_
);
return
(
1
);
}
return
(
0
);
}
pd/src/s_stuff.h.in
View file @
81cd906b
...
...
@@ -71,8 +71,8 @@ extern t_symbol *sys_libdir; /* library directory for auxilliary files */
extern t_symbol *sys_guidir; /* directory holding pd_gui, u_pdsend, etc */
/* s_loader.c */
typedef int (*loader_t)(t_canvas *canvas, char *classname); /* callback type */
EXTERN int sys_load_lib(t_canvas *canvas, c
har *file
name);
typedef int (*loader_t)(t_canvas *canvas,
const
char *classname
, const char *path
); /* callback type */
EXTERN int sys_load_lib(t_canvas *canvas, c
onst char *class
name);
EXTERN void sys_register_loader(loader_t loader);
/* s_audio.c */
...
...
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