Develop and Download Open Source Software

Browse CVS Repository

Contents of /netruby/netruby/Loader.cs

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1.1.1 - (show annotations) (download) (vendor branch)
Mon Apr 8 13:27:33 2002 UTC (22 years ago) by arton
Branch: MAIN, vendor
CVS Tags: start, HEAD
Changes since 1.1: +0 -0 lines
initial version 0.8

1 /*
2 Copyright(C) 2001-2002 arton
3
4 Permission is granted for use, copying, modification, distribution,
5 and distribution of modified versions of this work as long as the
6 above copyright notice is included.
7 */
8 using System;
9 using System.Diagnostics;
10 using System.Collections;
11 using System.IO;
12 using System.Text;
13 using System.Reflection;
14 using System.Reflection.Emit;
15 using System.Security;
16
17 namespace arton.NETRuby
18 {
19 internal class Loader
20 {
21 private Loader(NetRuby rb)
22 {
23 ruby = rb;
24 loadPath = new RArray(rb, true);
25 features = new RArray(rb, true);
26
27 string baseDir = AppDomain.CurrentDomain.BaseDirectory;
28 loadPath.Add(baseDir);
29 loadPath.Add(Path.Combine(baseDir, "lib"));
30 loadPath.Add(AppDomain.CurrentDomain.BaseDirectory);
31 string lp = Environment.GetEnvironmentVariable("RUBYLIB");
32 if (lp != null)
33 {
34 string[] sp = lp.Split(new char[] { Path.PathSeparator });
35 for (int i = 0; i < sp.Length; i++)
36 {
37 loadPath.Add(Environment.ExpandEnvironmentVariables(sp[i]));
38 }
39 }
40 if (rb.SafeLevel == 0)
41 {
42 loadPath.Add(".");
43 }
44 }
45 NetRuby ruby;
46 RArray loadPath;
47 RArray features;
48 static string[] exts = { ".rb", ".dll", ".so", ".exe" };
49
50 internal void IncPush(string lp)
51 {
52 string baseDir = AppDomain.CurrentDomain.BaseDirectory;
53 string[] sp = lp.Split(new char[] { Path.PathSeparator });
54 for (int i = 0; i < sp.Length; i++)
55 {
56 if (loadPath.Contains(sp[i]) == false)
57 loadPath.Add(Environment.ExpandEnvironmentVariables(sp[i]));
58 }
59 }
60 internal RArray LoadPath
61 {
62 get { return loadPath; }
63 }
64 internal RArray Features
65 {
66 get { return features; }
67 }
68 internal bool Require(string s)
69 {
70 RThread th = ruby.GetCurrentContext();
71 ruby.CheckSafeString(th, s);
72 s = s.Replace('/', Path.DirectorySeparatorChar);
73 string fname = null;
74 bool script = true;
75 string ext = Path.GetExtension(s);
76 if (ext != String.Empty)
77 {
78 if (String.Compare(ext, ".rb", true) == 0)
79 {
80 fname = FindFile(s);
81 }
82 else if (String.Compare(ext, ".dll", true) == 0
83 || String.Compare(ext, ".so", true) == 0)
84 {
85 fname = FindFile(s);
86 script = false;
87 }
88 }
89 else
90 {
91 for (int i = 0; i < exts.Length; i++)
92 {
93 fname = FindFile(s + exts[i]);
94 if (fname != null)
95 {
96 if (i != 0)
97 {
98 script = false;
99 }
100 break;
101 }
102 }
103 }
104 if (fname == null)
105 throw new eLoadError("No such file to load -- " + s);
106
107 string fileName = Path.GetFileName(fname);
108 if (featureCheck(fileName)) return false;
109
110 if (script == false)
111 {
112 try
113 {
114 AssemblyName asm = AssemblyName.GetAssemblyName(fname);
115 Assembly a = Assembly.Load(asm);
116 Type[] tps = a.GetTypes();
117 foreach (Type t in tps)
118 {
119 AddType(t, th);
120 }
121 features.Add(fileName);
122 }
123 catch (FileLoadException)
124 {
125 return false;
126 }
127 catch (BadImageFormatException)
128 {
129 throw new eLoadError("Not valid file image to load -- " + fname);
130 }
131 }
132 else
133 {
134 int oldSafeLevel = th.safeLevel;
135 th.safeLevel = 0;
136 th.PushTag(Tag.TAG.PROT_NONE);
137 try
138 {
139 ruby.Load(fname, false);
140 features.Add(fileName);
141 }
142 catch (Exception e)
143 {
144 #if _DEBUG
145 System.Console.Error.WriteLine(e.Message);
146 System.Console.Error.WriteLine(e.StackTrace);
147 #endif
148 throw e;
149 }
150 finally
151 {
152 th.PopTag(true);
153 th.safeLevel = oldSafeLevel;
154 }
155 }
156 return true;
157 }
158
159 internal string FindFile(string fname)
160 {
161 fname = Environment.ExpandEnvironmentVariables(fname);
162 if (Path.IsPathRooted(fname))
163 {
164 if (ruby.SafeLevel >= 2 && PathCheck(fname) == false)
165 throw new SecurityException("loading from unsafe file " + fname);
166
167 return (File.Exists(fname)) ? fname : null;
168 }
169 ArrayList ar = loadPath.ArrayList;
170 string result = null;
171 lock (ar.SyncRoot)
172 {
173 foreach (object dir in ar)
174 {
175 string path = Path.Combine(dir.ToString(), fname);
176 if (File.Exists(path))
177 {
178 result = path;
179 break;
180 }
181 }
182 }
183 return result;
184 }
185
186 bool featureCheck(string fpath)
187 {
188 ArrayList ar = features.ArrayList;
189 bool result = false;
190 lock (ar.SyncRoot)
191 {
192 foreach (string s in ar)
193 {
194 if (String.Compare(s, fpath, true) == 0)
195 {
196 result = true;
197 break;
198 }
199 }
200 }
201 return result;
202 }
203 bool PathCheck(string fname)
204 {
205 string path = Path.GetDirectoryName(fname);
206 ArrayList ar = loadPath.ArrayList;
207 bool result = false;
208 lock (ar.SyncRoot)
209 {
210 foreach (string s in ar)
211 {
212 if (String.Compare(s, path, true) == 0)
213 {
214 result = true;
215 break;
216 }
217 }
218 }
219 return result;
220 }
221 bool AddType(Type tp, RThread th)
222 {
223 BindingFlags bf = BindingFlags.Public | BindingFlags.NonPublic
224 | BindingFlags.Static | BindingFlags.InvokeMethod;
225 MethodInfo mi = tp.GetMethod("Init", bf, null,
226 new Type[] {typeof(NetRuby)}, null);
227 #if REQUIRE_DEBUG
228 System.Console.WriteLine("type:{0} has {1}", tp.ToString(), (mi == null) ? "null" : mi.ToString());
229 #endif
230 // NETRuby's extended libray
231 if (mi != null && mi.IsStatic)
232 {
233 Scope.ScopeMode vm = th.PushScope();
234 th.PushTag(Tag.TAG.PROT_NONE);
235 Tag.TAG state = Tag.TAG.EMPTY;
236 try
237 {
238 mi.Invoke(null, new object[] {ruby});
239 }
240 catch (eTagJump ej)
241 {
242 state = ej.state;
243 }
244 catch (Exception e)
245 {
246 th.errInfo = new RException(ruby, e);
247 state = Tag.TAG.RAISE;
248 }
249 th.PopTag(true);
250 th.PopScope(vm);
251 if (state != Tag.TAG.EMPTY)
252 {
253 th.TagJump(state);
254 }
255 }
256 else
257 {
258 ruby.cDotNet.AddFrameworkClass(tp);
259 }
260 return false;
261 }
262
263 object require(RBasic r, params object[] args)
264 {
265 string s = RString.AsString(ruby, args[0]);
266 return Require(s);
267 }
268 object f_load(RBasic r, params object[] args)
269 {
270 object[] argv = new object[2];
271 ruby.ScanArgs(args, "11", argv);
272 ruby.Load(argv[0], RBasic.RTest(argv[1]));
273 return true;
274 }
275 object lpGetter(uint id, GlobalEntry gb, NetRuby rb)
276 {
277 return loadPath;
278 }
279 object ftGetter(uint id, GlobalEntry gb, NetRuby rb)
280 {
281 return features;
282 }
283 internal static Loader Init(NetRuby rb)
284 {
285 Loader ld = new Loader(rb);
286 rb.DefineReadonlyVariable("$-I", null, new GlobalEntry.Getter(ld.lpGetter));
287 rb.DefineReadonlyVariable("$:", null, new GlobalEntry.Getter(ld.lpGetter));
288 rb.DefineReadonlyVariable("$LOAD_PATH", null, new GlobalEntry.Getter(ld.lpGetter));
289 rb.DefineReadonlyVariable("$\"", null, new GlobalEntry.Getter(ld.ftGetter));
290 rb.DefineGlobalFunction("load", new RBasic.RMethod(ld.f_load), -1);
291 rb.DefineGlobalFunction("require", new RBasic.RMethod(ld.require), 1);
292 return ld;
293 }
294 }
295 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26