aboutsummaryrefslogtreecommitdiff
path: root/externals/loaders/libdir.c
blob: f52ad3f380a79972d7fd54ff068f42080e28eadf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include "m_pd.h"
#include "s_stuff.h"
#include "g_canvas.h"
#include <stdio.h>
#include <string.h>
#include <unistd.h>

/* WARNING: KLUDGE!  */
/*
 * this struct is not publically defined (its in g_canvas.c) so I need to
 * include this here.  Its from Pd 0.41-test03 2006-11-19. */
struct _canvasenvironment
{
    t_symbol *ce_dir;      /* directory patch lives in */
    int ce_argc;           /* number of "$" arguments */
    t_atom *ce_argv;       /* array of "$" arguments */
    int ce_dollarzero;     /* value of "$0" */
    t_namelist *ce_path;   /* search path */
};


static char *version = "$Revision: 1.6 $";

/* This loader opens a directory with a -meta.pd file as a library.  In the
 * long run, the idea is that one folder will have all of objects files, all
 * of the related *-help.pd files, a file with meta data for the help system,
 * etc.  Then to install the lib, it would just be dropped into extra, or
 * anywhere in the global classpath.
 *
 * Ultimately, the meta file will be read for meta data, specifically for
 * the auto-generated Help system, but for other things too.  Right now,
 * its just used as a marker that a directory is meant to be a library.
 * Plus its much easier to implement it this way, I can use
 * open_via_path() instead of writing a new function.  The grand plan is
 * to have one directory hold the objects, help files, manuals,
 * etc. making it a self-contained library. <hans@at.or.at>
 */

static int libdir_loader(t_canvas *canvas, char *classname)
{
    int fd = -1, i;
    char fullclassname[MAXPDSTRING], dirbuf[MAXPDSTRING];
    char reldirbuf[MAXPDSTRING], curdir[MAXPDSTRING], *nameptr;
    t_canvasenvironment *canvasenvironment;

/* look for meta file (classname)/(classname)-meta.pd */
	strncpy(fullclassname, classname, MAXPDSTRING - 6);
	strcat(fullclassname, "/");
	strncat(fullclassname, classname, MAXPDSTRING - strlen(fullclassname) - 6);
	strcat(fullclassname, "-meta");
	
	/* if this is being called from a canvas, then add the library path to the
	 * canvas-local path */
#if (PD_MINOR_VERSION >= 40)
	if(canvas) 
	{
		canvasenvironment = canvas_getenv(canvas);
		if ((fd = canvas_open(0, fullclassname, ".pd",
								dirbuf, &nameptr, MAXPDSTRING, 0)) < 0) 
		{
			return (0);
		}
		close(fd);


		// G.Holzmann: canvas will look to a relative path to it, so we cannot add
                // the absulote dirbuf path, we have to make it relative to the current canvas
		// (see from line 1561 in g_canvas.c)

		sys_unbashfilename(canvas_getdir(canvas)->s_name, curdir);
		
		// count depth of the current dir
		for(i=0; i<strlen(curdir); i++)
		{
			if(curdir[i] == 47) // 47 is "/" in ascii
                          strncat(reldirbuf, "../", MAXPDSTRING);
		}
		strncat(reldirbuf, dirbuf, MAXPDSTRING);


		// TODO: have this add to the canvas-local path only
		canvasenvironment->ce_path = namelist_append(canvasenvironment->ce_path, 
								reldirbuf, 0);
		post("libdir_loader: added %s to the canvas-local path", classname);
	}
	else
#endif
	{
		if ((fd = open_via_path(".", fullclassname, ".pd",
								dirbuf, &nameptr, MAXPDSTRING, 0)) < 0) 
		{
			return (0);
		}
		close(fd);
		sys_searchpath = namelist_append(sys_searchpath, dirbuf, 0);
		post("libdir_loader: added %s to the global classpath", classname);
		post("\tThis is deprecated behavior.");
	}
	/* post("libdir_loader loaded fullclassname: '%s'\n", fullclassname); */
    if (sys_verbose) 
        post("Loaded libdir %s from %s", classname, dirbuf);

    return (1);
}

void libdir_setup(void)
{
/* relies on t.grill's loader functionality, fully added in 0.40 */
#if (PD_MINOR_VERSION >= 40)
    sys_register_loader(libdir_loader);
#else
	error("to function, this needs to be compiled against Pd 0.40 or higher,\n");
	post("\tor a version that has sys_register_loader()");
#endif
    post("libdir loader %s",version);  
    post("\twritten by Hans-Christoph Steiner <hans@at.or.at>");
    post("\tcompiled on "__DATE__" at "__TIME__ " ");
	post("\tcompiled against Pd version %d.%d.%d.%s", PD_MAJOR_VERSION, 
		 PD_MINOR_VERSION, PD_BUGFIX_VERSION, PD_TEST_VERSION);
}